[Setup] Product=Gamebots Version=10523 Archive=Gamebots.umod SrcPath=. MasterPath=.. Group=SetupGroup Group=GamebotsGroup Group=umodIncludeFilesGroup [SetupGroup] Copy=(Src=System\Manifest.ini,Master=System\Manifest.ini,Size=509,Flags=3) Copy=(Src=System\Manifest.int,Master=System\Manifest.int,Size=294,Flags=3) [GamebotsGroup] File=(Src=System\BotAPI.ini,Size=1332) File=(Src=System\BotAPI.u,Size=290284) File=(Src=System\FriendlyBotAPI.ini,Size=2184) File=(Src=System\FriendlyBotAPI.int,Size=205) File=(Src=System\FriendlyBotAPI.u,Size=4005497) File=(Src=System\BotAPI.int,Size=749) [umodIncludeFilesGroup] File=(Src=Help\GamebotsReadme.txt,Size=3184) [Setup] LocalProduct=Gamebots ReadMe=Help\GamebotsReadme.txt SetupWindowTitle=Gamebots Install AutoplayWindowTitle=Gamebots Options ProductURL=www.planetunreal.com/gamebots/ VersionURL=www.planetunreal.com/gamebots/ Developer=Gamebots group DeveloperURL=www.planetunreal.com/gamebots/ [BotAPI.VizConnection] bDebug=False updateTime=0.200000 [BotAPI.BotConnection] bIterative=False bDebug=False visionTime=0.100000 [Engine.GameInfo] bMuteSpectators=False bLowGore=False bVeryLowGore=False bNoCheating=True bAllowFOV=True bExternalBatcher=False AutoAim=0.930000 GameSpeed=1.000000 MaxSpectators=2 AdminPassword= GamePassword= MaxPlayers=16 IPPolicies[0]=ACCEPT,* IPPolicies[1]= IPPolicies[2]= IPPolicies[3]= IPPolicies[4]= IPPolicies[5]= IPPolicies[6]= IPPolicies[7]= IPPolicies[8]= IPPolicies[9]= IPPolicies[10]= IPPolicies[11]= IPPolicies[12]= IPPolicies[13]= IPPolicies[14]= IPPolicies[15]= IPPolicies[16]= IPPolicies[17]= IPPolicies[18]= IPPolicies[19]= IPPolicies[20]= IPPolicies[21]= IPPolicies[22]= IPPolicies[23]= IPPolicies[24]= IPPolicies[25]= IPPolicies[26]= IPPolicies[27]= IPPolicies[28]= IPPolicies[29]= IPPolicies[30]= IPPolicies[31]= IPPolicies[32]= IPPolicies[33]= IPPolicies[34]= IPPolicies[35]= IPPolicies[36]= IPPolicies[37]= IPPolicies[38]= IPPolicies[39]= IPPolicies[40]= IPPolicies[41]= IPPolicies[42]= IPPolicies[43]= IPPolicies[44]= IPPolicies[45]= IPPolicies[46]= IPPolicies[47]= IPPolicies[48]= IPPolicies[49]= ServerLogName=server.log bLocalLog=True bWorldLog=True bBatchLocal=False DemoBuild=0 DemoHasTuts=0 *E@""*ZHwB"None SendLineBotAPI PlayerPawn BotFaces BotNames BotClasses BotSkins RemoteBotAddBot BotTeams GetArgValCoreSetProgressMessage NeedPlayersEngineBotstartupBegin SpectatorLogTeamChangeinFront ChangeTeamDying GetGameInfoGetGameStatusSetProgressTimeBotpackGutHit StillFrRpTournamentPlayerRemoteBotInfo Commander StartMatch TakeDamage ClearOrders TooManyBots FlushLogLogPlayerConnectPostBeginPlay RightHit ParseVectorClearProgressMessages SetOrdersClientReplicateSkins AddRemoteBotSpawnRemoteBotRunSmTimer StillSmFrSystem DuckWlkS SkillTauntsFindPlayerStartTweenToRunningTweenToWaiting StopWaitingRestartPlayerPlayTeleportEffect FallingStateSkillsLeftHitRunning Fallback JumpSmFrDead3 PlayDecap ReBalance JumpLgFr SpecialNavig WarnTargetRoamingDied AddToTeam LongFall DuckWlkLWalkSmEnemyAcquiredWalkLgSetText HurtOtherEndGameCHIndividualizeRunLg GetValue SuicidedMoveMesh BeginStateCHGetBotClassUWindowDoneDead2WaitingForStart PlayWaitingLanded GetBotTeamChooseBotInfo GameEndedSetFall monitoringDead9Defend AcceptedSelectionMesh OneOnOnePlayStartUpMessage TeamSkin2IpDrv FreelanceProcessAction bAllowFOVNetWait FaceSkinListen CountDown ReceivedLineDefaultPackage MakeItem SendText MinPlayers ReceivedTextDead1 CarcassTypeDefaultSkinName WalkLgFrAimDnLg ReduceDamageDead7 bLocalLogDead4 bPauseable BotMenuTypeRunSmFrServerReStartPlayerHeadHitRunLgFr WalkSmFr ForceAddBotLogSpecialEvent MenuName InitialBotsAddDefaultInventory RestartGame GameName TimeMessageLogoutAS PlayInAir PlayRunningTestCloseDead8 PlaySwimming PlayDyingFollow SetBotOrdersSetAttractionStateFor SetHelpTextSwitchToBestWeaponAnimEndTweenToSwimmingAimDnSmGetSelectedIndexInitforbBalanceTeams BaseChangeWaitingForInitbPlayersBalanceTeamsPlayDyingSound TrackingJumpingAimUpLgTreadLgCreatedSetFontDead5PlayVictoryDanceAimUpSmae SeePlayerib SetValueDucking VoiceType TryAgainTaunt1 ZoneChangeForceMeshToExistStrafeCreateControl Victory1 PlayRightHitTreadSmTurning checkVisionUMenuTweenToFalling PlayGutHit PlayLeftHitStrafeL checkSelfSendVoiceMessageshotVoicePackMetaClassDumbDownChangedPickupEnemyNotVisible Decapitated BeginPlay FixedSkinKilledzappedRemoteFireWeapon AdjustAim RemoteJumpStrafeRFireWhileFalling GetSpeed LostChild PlayLandedBreath1FireAltFire PlayFiring GainedChildTeamBroadcastChangedWeaponTakeHitChat1Thrust InitRecievedAlternatePath Breath1L Breath2L ChangeNameTweenToFighter StillLgFrWalkBalanceTeamsChanged ParseRot checkGameWaiting HaltFiring StopFiring LandSmFr PlayDuck PlayHeadHit LandLgFr PlayTurningBumpSwimSmSwimLg SetMultiSkinHeld ControlPoint PlayWalkingsplash BindPort AcceptClass ListenPortPlayChallenge TryToDuckAttackBreath2 SetEnemyClosedMaxConnectionsSendGlobalMessagePlayFeignDeath LightEffect SpecialFireCheckFutureSightSendTeamMessage LightType Buoyancy PlayDodge bIsFemale PlayRisingTweenToWalking UnderLift ClientDying LightRadiusTeamLightSaturation FearThisSpotPlayWeaponSwitch AdjustTossLightBrightness DrawScaleStyle bIsHuman PlayRecoil OwnerJumped DifficultyBotVoiceMessageIdleTakeFallingDamageSetHandGestureDrowned HidePlayer AddInventory GetMultiSkin JumpSound DownWeaponPutDownCollisionHeight SpawnCarcass SaveConfigsFighterCollisionRadiusAlterDestinationSetMovementPhysicsBroadcastMessage PlayCrawling FireWeapon TeamMessage PreBeginPlayClientMessageInventorySpotGlobal HearNoiseTickMayFall PainTimerHeadZoneChangeFootZoneChange EndStateHitWallTriggerLoadCurrentValuesConfigureIndivBots LightHueRandomChecked VizServerRemoteUTBotConfigSClientVizConnectionRemoteTMale2BotRemoteTMale1BotRemoteUTBotConfigClientRemoteTFemale1BotRemoteMaleBotRemoteTFemale2Bot PathMarkerBotTeamGamePlusPathMarkerMutatorBotDominationBotDeathMatchPlus BotServerBotConnectionBotAPIConfigMenuItemBotAPIConfigMenuMinPlayersHelp DumbDownTextBalanceTeamsHelp VictoryDanceTurnLg ClearControlCanImpactJumpYellAt PlayFlip SpawnWait TeamSkin1PlayLookAround PlayWaving MaybeTaunt ImpactJumpInitializeSkill HearPickupFindAmbushSpotCockGun Alertness FastInAirDodgeRBackRun MenuHelpExecute MenuCaptionNumBotsChangedAutoAdjustChecked BaseChangedremoteVisionLimitRemoteHumanBotRemoteFemaleBotBotAPIConfigMenuCWMinPlayersText PlayFallLook DeathEndUWHit2 CockGunLBaseEyeHeight DeathEnd2drownTurnSm DeathEnd3 EyeHeightCloseToPointManDead11TranslocateToTarget StatusBelt StatusDollSetPeripheralVision LandGrunt updateTime bAllowPause BotAccuracyDead6ImpactJumpingBigJumpBalanceTeamsText BeforePaintNotify ReSetSkillWave SendHomeDodgeL visionTime ClientClass SetMaxLengthSetSelectedIndex ShowModal bIterativeSetNumericOnlyBotCTFSetNumericFloat DumbDownHelp WindowTitle MessageBox FortStandard MovingFireUWindowComboControlUWindowClientWindowUWindowFramedWindowUWindowSmallCloseButtonUWindowDialogClientWindowUWindowEditControlUWindowWindowdistUWindowPulldownMenuItemUWindowScrollingDialogClientSecond GetParent NoiseMaker TimeSecondsAlignWinLeftUWindowCheckboxUWindowDialogControlRootIconsUWindowRootWindow PawnList Translocator bVeryLowGore newFootZoneOwner bPainZone nextPawnSimAnimspeed LinkStatePausercarc AnimRateNavigationPointListNetModeLandUWindowPulldownMenuUWindowLabelControl ViewRotationSetSize CreateWindow bMeleeWeapon WinHeight CenterWidth CloseButtonGame RecipientPRIWait MessageTypebWaitingPlayerbIsABotHasFlagfirstScore WinWidthFixedAreaClass bPointing NumPlayers bTeamGame GameClass HeadRegion PainTime bWaterZoneSkill Velocity bByParentTcpLinkbIsMultiSkinned bReadyToPlaybBeep TimerRate bDrowningbCanFlyRateEventInstigator bCheckedSender MultiSkinsDamage HitLocation bUpAndOut NewWeapon Momentum projSpeedshooterNKillerP LevelNameZoneusealtHitLocTeamsNum bAltFirebFireCharge NextState NextLabelOldMessageTime bGameEnded LoudnessConnectionCount ReceivedDataRemainingTime AmmoAmountbStopCountDown RouteCache AccuracyFireDir aimerror projStart bRapidFirebNoCRLFRegionEnteredMessage MaxPlayersTargetbRecommendAltSplashDamageDamageScalingHealth PointRegion Location AirControlJumpZbRecommendSplashDamage GroundSpeedControlOffset CenterPos bCanJumpEnemyFemaleMale TeamInfo VoicePack MaxTeamsBotConfigType bIsPlayerbIsPawn MaxTeamSizeSize bCanDuck OldEnemybReadyToAttackbNoClearSpecial OrderObject NextAnim LastPainTime FireSpot FireRotation TargetDist TossSpeed TossTime enemyDistduckDir NewEnemynextNavigationPoint AmmoType SeenPlayer MessageIDPendingWeapon PRIArray PlayerNameMVel2D bDuckLeftLoc2DDest2DAnglemoveDirMLand3 FragLimit TimeLimitNumBotsRemainingBotsBotNbSpawnInTeamAreaId Acceleration NextBotTeam DesiredTeamNewTeam SmallestTeam bAdjustSkill bRandomOrderaPawn AccelRate NextBotClass NextBotDesc TeamIndex decisionbDamageTriggered bUseAltMode BotConfigNewBot ConfigUsednewAnim mdrown2fem RotationRateType AnimSequenceOrdersMass HitActor impactVel bIsAnArmor bOverTime PlayerID HitNormalNewZone newHeadZoneAtLeastOneBotTextAtLeastOneBotTitleUMenuLabelControlUMenuBotConfigBaseUMenuBotmatchClientWindowUMenuModMenuItem ControlWidth ControlLeft ControlRightBotmatchParent Initialized BaseCombo TauntLabel NumBotsEditAutoAdjustCheck RandomCheck ButtonWidth ButtonLeft MenuItemPhysics SightRadiusDeathMatchPlus DamageTypebHiddendepthtempASpot TeamGamePlusAChallengeBotInfoXCEZYPitchRollj LastSeenPosPeripheralVision TweenTime SkinNamei WalkingSpeed ScriptTextSVBYawOtherR DeltaTime Selection ReturnValueStaticSaveConfigDynamicLoadObjectCTFGame ZoneGravitySetPropertyTextRemainingMinute DominationMutator ElapsedTimeTimeBetweenAttacksFocusWeapon LevelInfo GameInfo ZoneInfoCarcassNavigationPointInv MoveTarget Destination MoveTimerNewItem FootRegion instigatedBy RotationbAdvancedTactics bCountJumps FaceNameTeamNumCTFFlagCrystalPlayerReplicationInfoStatLogCountDownMessageNotReadyMessage ReadyMessageWaitingMessage2WaitingMessage1Info RestartWaitbAlwaysForceRespawn bDumbDownTournamentGameInfoBotReplicationInfoUT_HeadFemale UT_HeadMaleUT_FemaleFootTMale2CarcassTMale2TMale1CarcassTFemale2CarcassTFemale1Carcass TFemale1bHomeCTFReplicationInfoTMale1 PointDiedSelectionWeight CommandoTMJump3SoldierWoman WomanBelt FCommandoSGirlbInitLifeMessagebNovicebImpactJumping bPowerPlay bBigJump bTacticalDirbNoTactLastAcquireTimeOldMessageType OldMessageIDBaseAlertnessMyTranslocatorMoron NewOrders OrderGiverbNoAckrealYaw TargetLook TargetVel FireDist bDefendMeleeDestn JumpDest bRatedGameHolder FlagList RealOrdersRealOrderGiverbForceRespawnbRequireReady bNetReady StartCountLastStartSpotNumCommandersEndTimeaBotGameReplicationInfo bBalancingbigsmallbigsize smallsize OldStartSpotMinSizeLeaving totalWeightpartialWeightControlPointsDomScoreEventCP bReturnOnlyControllingTeam Controller bScoreReadymyFlagbCleanDesiredTargetbReadyOutStrUTMenuAmmo InventorySkin enemyDirFocus2DUTConfigIndivBotsWindowv2BalanceTeamsCheckDumbDownCheckCanvas bJumpOffPawn TempActorMessageStringHitVec HitVec2DinjureddotpbResult strafemagVelDirTextLevelMoveraPlayerExiting WorldLog StartSpot bDeleteMe CurrentID LocalLog bIsWalking OtherDir leadTarget bReversedbDebugbNoTeamChanges myConnection RemoteEnemyRemoteDestination RemoteFocus myTargetmyDestinationmyFocuslastWallHitTime lastBumpTimeActorPawnbFallLodMesh DescriptionSound RemoteTargetTextureClassParent outstringPackageHitLHitNRot RecievedArgs RecievedVals tempBooltheBotGoalTeamScoreMUWHit2 gameInfoStr TextBuffer clientName teamStringcmdTypeargBodyremendloc wordsplitattrNum curBotStateObjectargName argValue FunctionvecNamedelimStateRotator boolResultrotTargoutBuf focusTargVectorStructbBound ArmorAmountlookDir sentNavs UnrealShare plrString isVisible sendUpdaterepeatnavType theVizServer theBotServerbServerLoadedRemoteBotConfigNumRemoteBots StrPropertyStructPropertyClassPropertytheConnection NamePropertybInitedPortBoxObjectPropertyFloatProperty BoolProperty IntProperty BytePropertytu B 7\[L] #tttttttt{#Ut{#UtX'tt #tГГГГ #ГГyrүyrүyrү #yrүyrүyrүw4w4w4w4w4')L')L #w4 #w4w4 # amxj\j\j\j\j\tj\j\j\j\ #ГГГГ{#U{#UX'ѸB # ##fIn#fIn-%n #ԝX11111111ԝXtt # #2Rtt #tt #ttttttttttttX'ttttt1t1ttttttttX'X'tttttttttttttttt111tttttX'ԝXttt111tX'X'ѸBX'X'Г #ԝXԝX #tԝX #ԝX #X'X'X'X'X' #X'11[ # # #t{#U{#U # # # #Г #X' ~$4?@J@@@`F@~KW ^L #2![[ amxMnO-N]K!L4[[[{#U[[[[[[[[[[[[ԝX[ԝX[ԝX[[[[[ԝX[ԝX[[[[[[[[[[[[[[[[X'[[[[[ԝX[ԝX[[ԝX[[[[[[ԝX[ԝX[[[[[[[[[[[ԝX[ԝX[[[[[[[[[w4[[[[ amxMnO-N]K!L4[{#U amxMnO-N]K!L4 amx amx amx amxl gb$=S]{s]}u] @g ]  amx2!l D" K"S]{s]}u] C @y U@@R @so#t U[[[{#U[[[[{#U[{#U[{#U[ ]CommandoSkins.BlakeSGirlSkins.AryssSoldierSkins.MalcomCommandoSkins.LuthorFCommandoSkins.CryssFCommandoSkins.VisseSoldierSkins.KregoreSGirlSkins.CiliaCommandoSkins.Kragoth FCommandoSkins.Tanya SoldierSkins.Johnson CommandoSkins.Boris SGirlSkins.Vixen SGirlSkins.SaraSoldierSkins.OthelloFCommandoSkins.KylaCommandoSkins.GornSGirlSkins.AnnakaSoldierSkins.RikerFCommandoSkins.MaliseCommandoSkins.RamirezFCommandoSkins.FreylisSoldierSkins.ArkonSGirlSkins.SarenaCommandoSkins.GrailFCommandoSkins.MarianaSoldierSkins.RankinSGirlSkins.IsisCommandoSkins.GravesSGirlSkins.LaurenSoldierSkins.MalcomFCommandoSkins.Jaycef]YigalPaulJeffLewisMilindEdDanielBillJim Kevin Stacy Ulf Randy Yolanda Wei-MinGalSheilaAndrewDavid  Andrew MTaylorAaron RogelioJayChonJihieJafar BenaminMike  Jose LuisNicoHans "                         W$?t$?]BotAPI.RemoteTMale1BotBotAPI.RemoteTFemale2BotBotAPI.RemoteTMale2BotBotAPI.RemoteTMale1BotBotAPI.RemoteTFemale1BotBotAPI.RemoteTFemale1BotBotAPI.RemoteTMale2BotBotAPI.RemoteTFemale2BotBotAPI.RemoteTMale1Bot BotAPI.RemoteTFemale1Bot BotAPI.RemoteTMale2Bot BotAPI.RemoteTMale1Bot BotAPI.RemoteTFemale2Bot BotAPI.RemoteTFemale2BotBotAPI.RemoteTMale2BotBotAPI.RemoteTFemale1BotBotAPI.RemoteTMale1BotBotAPI.RemoteTFemale2BotBotAPI.RemoteTMale2BotBotAPI.RemoteTFemale1BotBotAPI.RemoteTMale1BotBotAPI.RemoteTFemale1BotBotAPI.RemoteTMale2BotBotAPI.RemoteTFemale2BotBotAPI.RemoteTMale1BotBotAPI.RemoteTFemale1BotBotAPI.RemoteTMale2BotBotAPI.RemoteTFemale2BotBotAPI.RemoteTMale1BotBotAPI.RemoteTFemale2BotBotAPI.RemoteTMale2BotBotAPI.RemoteTFemale1Bot]CommandoSkins.cmdoSGirlSkins.fbthSoldierSkins.blktCommandoSkins.dacoFCommandoSkins.gothFCommandoSkins.gothSoldierSkins.RawSSGirlSkins.VenmCommandoSkins.goth FCommandoSkins.daco SoldierSkins.sldr CommandoSkins.daco SGirlSkins.Garf SGirlSkins.armySoldierSkins.blktFCommandoSkins.dacoCommandoSkins.cmdoSGirlSkins.fbthSoldierSkins.blktFCommandoSkins.gothCommandoSkins.dacoFCommandoSkins.gothSoldierSkins.RawSSGirlSkins.VenmCommandoSkins.gothFCommandoSkins.dacoSoldierSkins.sldrSGirlSkins.GarfCommandoSkins.dacoSGirlSkins.armySoldierSkins.blktFCommandoSkins.dacoz4KRSgJQ&@Vf|@`^:;7@V`@h@{JuO ,'w4E2!l D" K"C!@\w[ tT>xd  Z@zv E t{0B yAP@+Dn@I@]U i6rK!L4'#t #t ֟w4w4[[ #[ #[ #[{#U[{#U#t #t [w4[[tttt{#Ut[> Y[[[[> Y[t[{#U[{#U[{#U[{#U[{#U[w4[w4[w4[[w4w4& & & & tttL]L]tL]L]L]L]L]L]L]L]L]L]t{#Ut{#Ut{#Utttttt{#Ut{#Ut{#Ut{#Ut{#Utt{#U& & tt{#U& & t{#Utxx[tttt{#UtttL]L]L]ttttt#fInL]ttt{#Ut{#UL]tttL]ttxxL]L]L]#fInL]L]ttt{#UL]{#UttL]tL]L]L]#fInw4w4ʇ`L]{#Uʇ`ʇ`w4w4w4ʇ`L]{#UL]ʇ`w4t{#Ut{#Uj\ttttttt{#Utt> Yttt> Ytttt> Yttt> Ytxx> Yttt> Y> Y> Y> Y> Y> Y> Ytttttttt> Yt'n 6'n 6'n 6'n 6 amx amx amxttt{#Utr[{#U[{#U[{#Uj\ amx amx amx,'w4E amx#t R eShSx"p"s"M"CoD]! BotAPI.RemoteUTBotConfigSClientP]Remote Bot Capture the FlagALY6~Mn}"##t #t ֟w4w4[[ #[ #[ #[{#U[{#U#t #t [w4[[tttt{#Ut[> Y[[[[> Y[tttL]ttxx[{#U[{#U[{#U[{#U[{#U[w4[w4[w4[[w4w4& & & & tt> Yttt> Ytttt> Yttt> Ytxx> Yttt> Y> Y> Y> Y> Y> Y> Ytttttttt> Yt'n 6'n 6'n 6'n 6tttL]L]tL]L]L]L]L]L]L]L]L]L]t{#Ut{#Ut{#Utttttt{#Ut{#Ut{#Ut{#Ut{#Utt{#U& & tt{#U& & t{#Utxx[tttt{#UtttL]L]L]ttttt#fInL]ttt{#Ut{#UL]tttttttt{#U amx amx amxttt{#Ut amx amx amx,'w4E amx#t R eShSx"p"s"M"CoD]! BotAPI.RemoteUTBotConfigSClientP]Remote Bot Team GameAHt [6kN]L#t #t ֟w4w4[[ #[ #[ #[{#U[{#U#t #t [w4[[tttt{#Ut[> Y[[[[> Y[t[{#U[{#U[{#U[{#U[{#U[w4[w4[w4[[w4w4& & & & tttL]L]tL]L]L]L]L]L]L]L]L]L]t{#Ut{#Ut{#Utttttt{#Ut{#Ut{#Ut{#Ut{#Utt{#U& & tt{#U& & t{#Utxx[tttt{#UtttL]L]L]ttttt#fInL]ttt{#Ut{#UL]tttL]L]L]L]ttxxttttttt{#Uw4')L')L')L')Lt{#Uw4& & 'n 6& {#U{#U& {#U{#Utt> Yttt> Ytttt> Yttt> Ytxx> Yttt> Y> Y> Y> Y> Y> Y> Ytttttttt> Yt'n 6'n 6'n 6'n 6 amx amx amxttt{#Ut')L')L amx amx amx,'w4E amx#t R eShSx"p"s"M"CoD]! BotAPI.RemoteUTBotConfigSClientP]Remote Bot DominationAIR\6LO--%ntttt[{#U[{#Uw4[{#U& & & & ttL]ttxx[ttt> Yttt> Ytttt> Yttt> Ytxx> Yttt> Y> Y> Y> Y> Y> Y> Ytttttttt> Yt'n 6'n 6'n 6'n 6t{#U& & tt#t #t ֟w4w4[[ #[ #[ #[{#U[{#U#t #t [w4[[tttt{#Ut[> Y[[[[> Y[t amx amx amxttt{#Ut amx amx amx,'w4E amx#t R x"p"s"M"CoD]! BotAPI.RemoteUTBotConfigSClientP]Remote Bot DeathMatchAf @i @JZ@XEtGiM@ b@k@r@l@@qKD@)UP@]TqW@v B G@Y ]a@L R@cq W\b*@lXM@IFFpuY d@`@^p  @R@Hu\mrQuPS_@y]}eD@K8{@\c @d1OTb@@O@.x@d@9@Q@i_X}l@m@dEM@`dG@PSj@t{L @hI@K@}@?[@ps@d@o@W Af@^@veZ@DO w  rbMn| @B 7DxM~]H]H]H]H]H]H]H]H {JFRQL]BotPack.VoiceFemaleUEMio VB 7 FWM~]H]H]H]H1 {L]BotPack.VoiceMalew e@Q @@a\CkG B 70M~[X'X'X'X'X'X'X'X'X'X'ѸBX'X'X'X'X'X'X'tX'X'X'X'X'X'X'X'X'1X'X'X'X'X'X'X'X'X'X'X'X'X'X'X' cH$AM$Aw$As$BS$BbIOLei O@xaF \h@`H,iZ@a[l@quX  hSo@q@I@JP xfO@cED@{z f@CmG~I @Y@ @v Rdu|y VBlTh B@g ^rs /ds[@~@3q ]I @|@_ r^\ MF.bG% - r* ::$ ::$ h-eG= Ga>> KM KZG=> \qkbM Kb\L? pppppppppppppPRJTimeUKZDirectionYPb GL @LVR@AS X V ZV%ia!A333?= CfJ"pmHJCbpUUppppppppppppDAMDamageSJDamageTypeWUStz_C WC _2WSL?UppppppUInstigatorVC U jWwE~ C@@x@$[0!( !pa&!xYL?a&!(xYa&!px ZfPN|,Ptp_] Se@Y ]qir qa!333? WwrT@F | oHkos`kppppppppppppDIEKillerVoDamageTypeWs z,{@e x sFs`[-^@y,H@I @zD VA,By@ @Ngqy|F@u @5@Oy@pb @@~@`@{@@Lo{ u@M ecbAhFwL! !\<?a&!=hIa&!(huh?a&!hua&!\h RW@Ukk@zt @t[ niU}l~w)[0!G !Ba&!~YL?a&!G~Ya&!B~ ~EIm Q;ʕ2!,'w4EMnO-N]K!L4ttttt{#Ut{#UtX'tttw4w4')L')Lw4w4w4ГГГj\j\j\j\tj\j\,'w4EMnO-N]K!L4,'w4El VU$L>S]{s]}u] |vG&[0!= !Aa&!vYL?a&!=vYa&!Av ^@QYT2XDR\dL|.XڨL}"#|.Xڨ}"#}"#tt+X-%nt+X-%nt+X᱘_4R_4R-%nR_4R᱘_4|.XڨR|.XڨRt+X-%n|.Xڨ}"#|.XڨLt.'lo R|.XڨRR|.XڨR|.Xڱ|.Xڱ|.Xڱ|.Xtt+X|.Xڱ|.Xڱ|.Xڱ|.X+X|.Xڱ|.Xڱ|.Xڱ|.XDZ 2[]Balance Teamsc]If this setting is checked, bots will automatically change teams to ensure there is a balanced number of members on each team.b]Enhanced Team AIk]SQEnable enhanced team artificial intelligence features for the bots in this game.B]Min. Total Playersa]sqBots will fill out the game to ensure there are always this many players. Set this number to 0 to disable bots.<  Experienced< Skilled<Adept<  Masterful< Inhuman< Godlike4They know how to kill.4Don't get cocky.4You think you're tough?4You'd better be good.4I hope you like to respawn.4You're already dead.4I am the Alpha and the Omega.G@KLN~XM>XSԝX 2bWa$?RN `2MS\ZUQ E=$ 7{.> j@Fu @O U^$Y::$333?Nr*?,a!AVa!mw*--:% :%a!?,a&!1>a&!>H-) #=!e @?U!e=r*?,a!s??>a!G??>>r*?,@?!] !HU;0?U!];U!Hz@?!i !jU?U!iU!jUaU>>aU>>> x]J( J`2[MZ 2chlMBotAPI Optionsy cW(%#w*Eq!; Z@^pad[`A hV>~ amxttttttZ 2fg @l@E@lr@o@@J@t@R @m@w p@B@P@Bn\k Fz@qM<gV@G  k @A @He@M  Z @J @} @t O ]PKv, {vIA|vIO vv V _y-JpRecieved - _HpH_PzH&, HH&~H, aHzH&, HHta::$ ~H, a v@Y Jaa T ot-JoOw*PaOP! P!b L~o}LL}o_oLho~ob%gb,  {hb~h&Zh&b&L~ZbnZLbIZL&hh&hh~hb__n_ e xg x Namef Team;zf~,G~Jfgf BotTeamGamePlus.M-x~e BotDeathMatchPlus.O-x~e &BotDomination.N-x~e bBotCTF.K-x~e 7zp(q!d!> U @S Yn-ycomandType:YY VPAUSES-HvizClient UNPAUSE|-H  ] ^ _ @` @a @h @f [ wQ!-yp Sending: w8-L wwOwppw, ,  l mgg '-JAccepted BotConnectionVgf qBotTeamGamePlusm.M BotDeathMatchPlusm.O BotDominationm.N BotCTFm.K }VZ~}.LEVELINFOaZ}}ZpppppppppppppNFOGametypegf&Level}&mq!d!g \ X S PKO, {OnA|OnSOIO c @H g j)'iQ r{QG~Qii,k~Qi6jLQkQQk&k~Qi6jLQk6jLQk& 6jL x6jL y6jL z @ nq1ppppppBEGTimeU]Y BotTeamGamePlus.M3 BotDeathMatchPlus.O3 BotDomination.N3 0BotCTF.K*3 ?w?*?-{ppppppppppppppppppppppppppppppppppppPLRIdV?RotationY? LocationX? TeamR?Name?WeaponV?:?%{pppppp{Firing1g:?%{pppppp{AltFiring2{pppppp{AltFiring0{??GGnwG*Ga/!r.G*Y,;Y.GppppppppppppppppppDOMIdVGLocationXG ControllerSYWW-PppppppppppppNAVIdVGLocationXG GG-P'/a0 n! na!Nn-ppppppppppppINVIdVnLocationXn 10/a0 DIppppppppppppppppppFLGIdVDTeamRDStateWDamDa!~IppppppppppppILocationXD HolderVDIppppppILocationXD I10ppppppENDTimeU H'X pg. glgi&gkn-JSpawned BotConnection | a  | a  Lp k@ [0!( !za&!kYL?a&!(kYa&!zk @` }Gz [0!= !ea&!}YL?a&!=}Ya&!e} r _ ib HtNB-yHV~H>VV}HbHVoH~Hu%(u,  {oD~olo&D&V~luIlVulV&oo&oo~oupbbnb  @j hpD#aP Rotation{PL~Paa,m~Pa6hDLPmPPm&m~Pa6hDLPm6hDLPm&!6hDL pitch6hDL yaw6hDL roll ay |BQFa!B =::$|a  #L?a<" @w|*|d| 6| 6| 6 Az YZi0Y!Ua!X = fY!P-B >a!\ = 6?, @??a!z =a!O = Y!K Y!Ta!e = {6\6333?-k?Bya!@ = 6- ?a!A =a!X = ^gq )dg,g>a!333?L>bPg333?a!f333?L>ba!z333?L> | a  @ KBoa!X =::$Ka  #L?a<" @wK*KdK 6K 6K 6 {'e-v{a ,{YBotCTFya yfBotCTF-v'a k } o *sylPyidykjpppppppppppppppppppppppsPGoalTeamScoresUdsPTimeLimitsSdsPMaxTeamssSdsPMaxTeamSizesSdj O@d P v$ppppP J  @PC E 7{.> Lk@ .!(a&!k,a&!(k ~ XBEylPyiMyk*GAM*ppp*EPPlayerScoresNwN*Na/!*pppppp*EPVNEUNMNN*p*M*ppp*EPTeamScoresh%h*pppppp*EPShEUhMhE*p*MwX*l:X.lwX**pppppp*EPHaveFlagEVXMwl*l-*pppppp*EPEnemyHasFlagE1M* T^r7a&!~> E@D E Yt7s J Y^36J333?@r*?,a!{Ha!| K k^50B3r*?,0wk*k?,t!/ !E!S0!L !I!N0!@!D0!K!30!1!0!b!~00!r!l@@rk*k?,!S !H!/@!N !}!L@!D!@@!3!K@ !!1@&!~!b@@!l!r N `H-~a%!o |4!S!H|Q!/!E|n!N!}|!L!I|!@a&!@<|!Da&!D<||a%!r2a%!k !m !A7?,a&!1 ף<|l- !a&! ף<||aa! M NTwd J+~-Vw*,a&!={{a ::$a! ף<!1a!1w ף<!m !a!mw ף< Plx$a!D>333?= D 0p_ J-+\%2%o\, \&%\%,-(*- %w * a/!. @   J< *-(!"- %% ` w * a/!. @  ::$ %-@' w * a/! a/!. --@(  4-@,%! w *x a/!. *V,  a/!. Qx.  pS%  , w * a/!. *. @.  %.  &g. -.  ,.  ,  ::$, w * a/!j.   - -::$ w * a! a/! -. F  c   % ;-8?O- %-(??,<?%%Qtimelimit R ol# 7o V p7}c::$333?Sr*?,a&!Ap`a&!mpw*P a%!r 6%666666f6Vr*?,a&!r>ca&!l>r*?,a&!b>a&!~>r*?,a&!1pa&!p T P DR_CwD*.D`DDa/!Da/!Da/!\Da/!   Da/!Da/!  :D#D]-- -C X {|C9r*?,a!3Aa!K U X9AXXkw3*3a/!$Destroying botXa(-fXXa/!.X3.Xr3*-f3*X3-$.3!fL?3-(3 +!f*'Xt(wt*t-3:t:3ta/!-h((ta/!.t!f-h'tt`X-h3-'3 +!G*'.3!G-fL?2Cw2*,2a/!h/:.2:3.2-R.222PR2w2*2a/!h/:.2:33.2N.2NP22f-f Z vr M>r*?,a&!3>Ka&!K> 2\ CTj(-Ca&!a>&a&!v> R] oTT333?ia%!kWr*?,a&!3@da&!K@ a%!wo@o333?r*?,a&!@oa&!Do ^ iu<333?ia%!kWr*?,a&!3?da&!K? a%!wi?i>r*?,a&!@ia&!Di Lb\"bbb=bbxb{.>a$@@b(D>L?6- b #<a$@bL>@(D?5bu=a%!k%r*?,a&!u=2a&!x=aXa%!d`r*?,a&!u=a&!x= Y|n _wp# [0!G !@a&!_YL?a&!G_Ya&!@_ A d [yv -ypRecieved - [JpJ[PzJ&, JJ&~~J, ~]J~~zJ~&, ~JJ~t]::$ ~~J, a W MCmF$~- % M%R%]%`%u&uu]Mu]uu`Ru`uuY-'']`&w*- :Ma/!a/!{.)!w{*{%{H*!U{ ]`{R$'-(|w*e-a/!a/!$.![f..erf*f-f-3:f:.*\.C i Jmu a w e @I@j \gJ#-yAccepted VizConnection]Y mBotTeamGamePlus\.M BotDeathMatchPlus\.O BotDomination\.N BotCTF\.K MVx~M.LEVELINFO]xMMxpppppppppppppNFOGametype]YLevelM\q!d!> J'?<4].,2-ySpawned VizConnection _ qU 03::$+9?%Y1^ u- -h-a!Hpa!X r6r^6^d6dur^Gd^quGq@?8q@a!wEu#?wEd^?%a!Ha!X r*W!/ -?,W!EW!H ?,W!/ W!S&Wa aW v Unb 5 -JcomandType:U9-OU aTEST q!!V3 sINITg3 INCH8 n?,d9   q!!V3 "SETWALK WalktempBool--K3 CSTOP q!!3 ^JUMPW3 `RUNTO Targetz)>Location n> q!!V]tempActor]w*b$   n  q!!V3 STRAFE)>Location n>q Targetzq)tFocus Kt6*wtempActorqww*b$  6 Kt8 q!!}3 nSHOOT Target)>LocationEnemyRemoteEnemy8 x> AlttempBool U-K3 MCHANGEWEAPON ID|best_JtempActorJw*.r*cJJwr3 |STOPSHOOT8s3 CHECKREACH TargetY idz)>Location-xb >ppppppppppppppppppRCHIDY&ReachableT-x&FromX &tempActorw*b$  -xbppppppppppppppppppppppppRCHIDY&ReachableT-x&FromX &ToX &3 h TURNTO TargetzpIw6I%6I%6I%)>Location K>6* K 9I?6*A tempActorA w*b$  6 K>8 q!!B3 a ROTATE AxisI 5J Amount zVertical6I6I5 6I6I5 K 9I?6*8 q!!B3  TRACK Target {tempActor b$  68 q!!j3 GETPATH5%z 5,Z r5@*z p 5@*5. )>Locationb>Y idmppppppPTHIDY&5% 5, r5@*  mppppppppmS5V5@X5@ &5 m3  MESSAGE Text-xK Global { -xbp@  b3 0 PINGPong3  k du!Dzqa{ !> >,lx jF`wL! !\<?a&!=jIa&!(juh?a&!jua&!Xj s@^ma!_333?L> LyWCr*?,a!K>>Ua!e>> \ $!,,-:$,(:$,#$:$G%GrG*%GGTGGGG-_&_hw_*Q_a/!_a/!h__w_*w_*8:_G$=,;:_\\;%;G$=,;,;%;G$=,;,;, ;;TQ$a/!$=,0w* $Ow* $'$a/! $=;w* $w* $':$;-($a/!.$*K;I;$'wG*GIT$'( @w gv/vgu Gx wC )_w)*Hw))-b$) ) #ra\`) )/ppppppppppppppppppppppppppppppppppppppppppppppppPLRIdV)RotationY) LocationX) VelocityX) NameTeamR)ReachableTb)WeaponV):)%/pppppp/Firing14:)%/pppppp/AltFiring24/pppppp/AltFiring0 /))/a8 wwa!Nw-w ra\`w *ppppppppppppppppppppppppINVIdVwLocationXw ReachableTbwClassVw10/a8 qBAq-q ra\`q *ppppppppppppppppppppppppppppppMOVIdVqLocationXq ReachableTbqDamageTrigTq-ClassVq100w0*b$0 0 ra\`0 *0a/!r.0*a, a.0ppppppppppppppppppppppppDOMIdV0LocationX0 ReachableTb0ControllerSappppppppppppppppppNAVIdV0LocationX0 ReachableTb000W zgfBotCTF/a0 @  b$@ @ w@/ppppppFLGIdV@ @a!~/pppppppppppp/LocationX@ HolderV@; /pppppp/LocationX@ /pppppppppppppppppp/TeamR@ReachableTb@StateW@a /10 | UIOU%V%B{wB*NB-UBdVdV,d{BB@ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppSLFIdVRotationYLocationXVelocityXNameTeamRHealthSWeaponVCurrentAmmoSArmorSU:%@pppppp@Firing19:%@pppppp@AltFiring29@pppppp@AltFiring0 @ z _A yP ppppppppppppppppppHITIdVeDamageSyDamageTypeWi s X]4Xa/!}wX*zXa!?X-'X 6=X q!?!EXa!GX-'X 6=X q!G!E N} Q #1<7}w}*}a/!}a/!r.}Q .} +!m*}} AC cZ(Pi0c!Ua!A = fc!P-B >a!@ = 6?, @?6q6- ?a!p L=::$Fa  #?wF*FdF 6F 6F 6a!\ = c!K c!Ta!e = f6q6333?-V?Bda!A = ?a!B =a!z = \ I{q|I(Na=PIx?6N #FZ?6N #FZ(z'  N -=8'.VN Ar'*Failed to spawn remote bot*'=e{M '=e"- -D%e%t&ttDDtett@e:''=,'-'e,'e'%-XVV5'=,{wV*'a V 'a+V ' V 'a+' V :''VXV :''w* &'%w* &'%\' ^B nq n,n>a!333?L>Pn?a!f333?L>tn@?a!z333?L>a&!zL> I gag6T333?Er*?,a&!{gRa&!|g G XT3*z$$-(* 'H 9>i-9C--?S-33>##^o$+..'q!a!bq!!y ]I c:8 Yu J:/ J K B N J?E=::$&\&  M P i?\, O R @*-\ f s.[A`gas5*=,`rs*Could not find starting spot for RemoteBot*a Yg s s r*pCouldn't spawn player at VsXw*eee&e= `gRg s N- % q!!]X::$--SXwS*AS-wS*S-Sa/!-.SH,% & , , A.S,SSN |_y [/--ypRecievedTest in Server - _ O dvv<Ta@ !gw*za!ba!ppppppBEGTimeU&gf BotTeamGamePlus.M &BotDeathMatchPlus.O ^BotDomination.N BotCTF.K  ICppppppENDTimeU&$-OaF !> >g4n Y fZ H:̌ D E ]-"-q!baL>;-tL-ma>.j9 !y-' ]y; i` X,‹_$$6a(((o$# FIN ^ g _ Y( Q's-YQa ,QYBotDomination|a |fBotDomination-Y'@a @k a c *j|lr|is|kdpppppppppppppppppppppppjrGoalTeamScorejUsjrTimeLimitjSsjrMaxTeamsjSsjrMaxTeamSizejSsd j@d e j f S%[ b i ?T|lZ|i`|k GAM ppp TZPlayerScoresfwf*fa/! pppppp TZVfTUf`ff p ` ppp TZTeamScores|%| pppppp TZS|TU|`|E p ` ppp TZDomPointse%e,we*4re*u,Wue pppppp TZVeTSu`e p `  T@k J" n c l o m F܊ t O p h ~0v -wL>j%j?>?_?=?wL?jw>B- %~Bw~*D.~+wD*wD*D-DwDw~~,%1%j1,`1?%w*3Kdom_score_updateS1U1`w*3Kdom_score_updateS1U11c1%1, A1wA*w*=Kdom_playerscore_updateSASDAw*=Kdom_playerscore_updateSASDA1q?%1%1,1Qteamscorelimit1=-c%%%bc, c&%c%,-(- w * a/!. @   =/ -(! - %s% S w * a/!. @  ::$ %-~' w * a/! a/!. --~(  '-~,%! w *k a/!. *I,  a/!. Qk.  pS%  , w *u a/!. *. @.  %.  &Z. -.  ,u.  ,  ::$,   w * a/!j.     - -::$  w *  a! a/! -. F  V     %  . -+ ?O  - %-( ??,<?% %Qtimelimit  q sx s Fq u v fC w H r WR8,'fWWIWa/!Wa/!dWa/!cWa/!   Wa/!Wa/!  :W#W%-- -C y { _9Q __^._w^*^a/!^!f^ +!m*w^*^a/!$Destroying bot_a(-p_ _a/!._-p | ^~ S a Cv " \] b5iF X  MM Z8M B Xg6/--yAccepted connection in BotServer ]G LW)s@.sWWarskw@*@'PD?WsarW `Mu}8M J fOi}8O T Qvo<$ppppQj& @AY@yQ _Oz\w*A6A\A ?%#\6i633%q!;!_q!;![ l vc;Q!-Jp Sending: v8-OwvOwppv, ,  M U EVIFSz 8IV Y HMX*H>a&!E?VIH+?a&!I?Va&!L? k V!>a&!3333? Ag(/--oAccepted connection in VizServer ] n{6x68{n4n-7>q!;!A c a*sL.iaa[]ikwL*L'PD?ai[]a ` `1xT GA #16FwF*Fa/!Fa/!r.FA .F +!m*FF b @e&3::$+9?%Y1^ Tr*a!n-?,a!Ia!}?,a!La!N h f,Tx8f "^ @ -=8(.`@ Ar(*Failed to spawn remote bot*(=l{k(=l"- -K%{%v&vvKKv{vv@{:((=,(-'{,({(%-i``5(=,{w`*(a ` (a+` ( ` (a+( ` :('`i` :('w* &(%w* &(%c( c m6B=::$09?%am;7m ar*]!/-?,]!E]!H?,]!/]!S]#a a&]m p aW#1;::$09?%aa;7aar*a&!na-?,a&!Iaa&!}a?,a&!Laa&!Na ~my20-opRecievedText in VizServer - m (Q T $x@\ ve[Le^~^ ::$x-yBotServer: Listening again - connections have been closed.r saF(+x k ];~(::$ ![*a?L>;b !YO-o$ ![a333?6?j366 66 o$6zC !Jv!`a?!-($! !;q?Going from -Doneq!t-g!vlL>ta&=-(!qGoing from -Splashq!-6-o$q6?, w*O>A66 66  L>?,9?%iE::$ ![f---a>SaL>86?,<6?,<a=#a?-(-(na@ !J66 66 -a>T wtCAt[_J;Y}0w z j dw,!!!TakeHitq  a m JG>E=::$&c&  l o i>c, n q G?*-c p s $?c r u.@`R@au5*=,`ru*Could not find starting spot for RemoteBot*a@ YR u u r*pCouldn't spawn player at VuXw*@@@&@=@ `R@RR u N- % q!!]X::$--eXwe*Ae-we*e-ea/!-.eH,% & , , A.e,eeN v 0Sr x I_!r 8_I Cy {"q!8"{}~EG Xqy Cu Xr@?::$##^aA !$y**vaA !V-@UanZn !V !Ur6*anKan6n !} !X::$##r6*b$6  !ya6aL= !j::$##w6*a6aK ! Bj}V}VS~ { rbk( C } Z|k h'w-Bha ,hYBotTeamGamePlusza zfBotTeamGamePlus-B'Ca Ck @ B (xzlWzilzkKpppppppppppppppppppppppxWGoalTeamScorexUlxWTimeLimitxSlxWMaxTeamsxSlxWMaxTeamSizexSlK x@E  o{j F D gwzj( K fPqif A H <~bzlRziQzk9GAM9ppp9bRPlayerScoresdwd*da/!9pppppp9bRVdbUdQdd9p9Q9ppp9bRTeamScoresZ%Z9pppppp9bRSZbUZQZE9p9Q9 b@I L J Jei N MZ{h R DSBf 1rDjD?j0>% Trj*jrj*ppppppppppppppppppKILIdVjKillerVDDamageTypeWh G pRXp>pa/!pa/!Ypa/!dtpa/!   pa/!pa/!  :p#p-- -C O ]Cs ~- % ]%^%U%X%r&rrU]rUrrX^rXrrY-''UX&w*- :]a/!a/!}.)!w}*}%}H*!U} UX}^$'-(|w*e-a/!a/!$.![V..erV*V-V-3:V:.*\.C U P n74f S X T N/e' V sW F%e KQ Nsj.pNNbTpkwj*j'PD?NpbTN ^ LV<I_  .y1r *$$hb$     - a/!nP  .  L  !D?!?, ?,   L  ?  -ww * -L?-w!?L?%L?@B-!?!?\B>-,-w!D?!@L>L> ::$: :$!? !D?!?> ?,F> ::$: :$!?-)?,?$ @?,-w!ff?!?,-` ?%!D?! -` L?%p  : :$q6   6   6p 6p6p6p?333??pLL66  6: :$  ?.?z  a: :$6z%9z  5?-8(-8b$.-8b$. -8>   ?  -8( ---w w*2-- :%: :$%6?,P6  L6?,6  #-w @?CacS#? ?,(-8rC*-8c#@@-8b$.: :$-8b$.-8(-866  -8b$.d-866  fff? -8b$.P.F6!,!!66! ?66? )?66? 669666666  66 U9y.C.yUCacS.( wC* 6S333?6F!= ?66? )?66?! 669666666 = 66 U9.yUCacS.( wC*S?,  -CacS.( wC* SU.PUL -w w * FLU c T_c8-.y>T?%VTF+-{-Vr-*b$- - 4- I- F{--b66 66  ITlIT64>66 l?,l?,<P4F+D?+?, ?, - I- ?- F-^r-*--I?+D?+ff@L>j+@?>+ff?+D?+?33>?,>+?{-)?,?$ @?,+?-{ ?%+D?+"-{4?333?? IT"b$4F4?4- 646- b$4F4TaOP4F(wT*$$4ի?,-Pa(@?WT>66 66  IWlIW64>66 l?,l?,<P4Fu6+,++66+?66? )?66?669666666 66 O9TaOPF4FCOF(SwT*6P333?6u+G?66? )?66?+669666666 G66 O9-V w-*-FTO jZ %,-:%,(:%,#%:%g%grJ*%Jg\gJgg-_&RhwR*QRa/!Ra/!hRRwR*wR*8:RJ%=,7:R\\7%7J%=,7,7%7J%=,7,7, 77\Q%a/!%=,0w* %Ow* %'%a/! %=7w* %w* %':%7-(%a/!.%*K7I7%'wJ*JI\%'( ` e b P{6' gf HUzC4w*Hw*%-' `-H$$ _?$$ ^? i |v 4 h Rl Wh/3=o$-e6-'c a Z]$mZa/!}wZ*zZa!?Z-'Z 6=Z q!?!EZa!GZ-'Z 6=Z q!G!E q j t, k K #<HwH*Ha/!Ha/!r.HK .H +!m*HH cm 0LJ-+d%2%od, d&%d%,-(*-%w*a/!. @ J< *-(!"- %% `w*a/!. @::$ %-`'w*a/!a/!.--`(4-`,%!w*xa/!.*V, a/!. Qx. pS%,w*a/!.*. @.  %.  &g.-.  ,.  ,::$,w*a/!j.- -::$w*a!a/!-.Fc   % ;-8?O- %-(??,<?%%Qtimelimit r o B*ppppppppppppHRNSourceClassVcRotationYPc  YXq_)WLppppppHRPRotationYPX  p x--".^xAr"*Failed to spawn remote bot*"=m{w"=m"- -O%[%E&EEOOE[EE@[:""=,"-'[,"[FUCK"%-t^^5"=,w^*"a ^ "a+^ " ^ "a+" ^ :"'^t^ :"'w* &"%w* &"%d" s[ L F:% @ "z Xz%?%a?(GG?, TG6T_X 6___T_L?66T66TGC?`nppppppppppppBMPIdVXLocationXX `v!z | iI $?\ppppppppppppppppppWALIdVfNormalXiLocationX\ ~ { ]# J} c~ QSr#r*_IIa!qq!h*Yw*:%$$ ^?:%$$ _? jkppppppppppppCWPIdVClassV t @J%'4E=::$&d&   Bi,4d, AD1'5*-d CF$65d EQ9?76QQS.Q{wS*Sa/!$Destroying botQa(-|QQa/!.Q-| SKHEc % -6-6--6",*#?#!l%@ MSNbq-333?K2?,LKff&?>fff? Gz.Ud8`JCaz5*=,`rz*Could not find starting spot for RemoteBot*aC YJ z z r*pCouldn't spawn player at VzXw*&=C `JCRJ z N- % q!!]X::$--aXwa*Aa-wa*a-aa/!-.aH,% & , , A.a,aaN N}{>dK}5ppppppZCBIdV} PAF8KA5ppppppZCHIdVA TCG20KC5ppppppZCFIdVC QRUS+I \mgu.:F: ppppppppppppppppppVMGSenderVFTypeWmIdRR VE'{-LEa ,EYBotDeathMatchPlusAa AfBotDeathMatchPlus-L'qa qk XZ(tAloAi|AkRppppppppppptoFragLimittS|toTimeLimittS|R t@na[}C8ppppppVMTStringn ]Y`:HAleAi[AkBGAMBpppBHePlayerScoresRwR*Ra/!BppppppBHeVRHUR[RRBpB[B H@bB C8ppppppVMSStringB cvLD|Dt:A :tJvt!A ejQQ|Dc:ds :dcJjcd![ hQnQkppppppppppppAINIdVQClassVQ _n.T+`Qqan5*=,`rn*Could not find starting spot for RemoteBot*aq YQ n n r*pCouldn't spawn player at VnXw*SSS&S=q `QqRQ n N- % q!!]X::$--LXwL*AL-wL*L-La/!-.LH,% & , , A.L,LLN kgh; ljZ -? rBD -B-&-Bq!!hppppppppppppFALFellT-BLocationX--B fOO=X=w* O\w* OOoOWyO}OWy=X' nWo|qf~  "mtJvE=::$&]&  svi], uxv*-] wz$] y0DJ-+]%2%o], ]&%]%,-(*-%w*a/!. @ J< *-(!"- %% `w*a/!. @::$ %-F'w*a/!a/!.--F(4-F,%!w*xa/!.*V, a/!. Qx. pS%,w*a/!.*. @.  %.  &g.-.  ,.  ,::$,w*a/!j.- -::$w*a!a/!-.Fc   % ;-8?O- %-(??,<?%%Qtimelimit }sY't%w* Co: @tRC$$ {VK!sz.{VVx^{kwz*z'PD?V{x^V B!L CAXEM Gx> z6c9ZL"ccw.c{ww*wa/!$Destroying botca(-ccca/!.c-c Z@waclass VizConnection expands TcpLink config(BotAPI); var string ReceivedData; var string RecievedArgs[9]; var string RecievedVals[9]; //used to store info inside function where local wont work //set property text dosent seem to work with a local var actor tempActor; var VizServer Parent; // set true to allow viz clients to pause var config bool bAllowPause; // set true for verbose debug logs var config bool bDebug; // delay between visionUpdates var config float updateTime; // record once we have sent navs - don't need to duplicate var bool sentNavs; // configurable delimeters for strings sent to clients // currently of form (with multiple possible attributes): // "type"$ib$"identifier"$ib$as$"attrname1"$ib$"attrvalue1"$ae // as = identifies the start of an attribute var string as; // ae = attribute end var string ae; // ib = item break var string ib; //------------Message Types--------------------------- // Each message appears on a seperate line. The first item // of each message is the type identifier. It is a three // letter code identifing what the message contains. // Used types are: // (Asynchronous messages) // (Synchronous messages) // PLR - see another player // INV - see an inventory item (or weapon) // NAV - see a navigation point // DOM - see a domination point // FLG - see a flag // END - end of a vision batch // BEG - begin of a vision batch // GAM - random information about the game //-------------------------------------------------- function PostBeginPlay() { Parent = VizServer(Owner); if(bDebug) log("Spawned VizConnection"); } //Socket established event Accepted() { local string gameInfoStr, levelName; local int i; if(bDebug) log("Accepted VizConnection"); //no clean way to do this since gametypes are not derived from //a common ancestor switch(Parent.gameClass) { case "BotTeamGamePlus": gameInfoStr = BotTeamGamePlus(Level.Game).GetGameInfo(); break; case "BotDeathMatchPlus": gameInfoStr = BotDeathMatchPlus(Level.Game).GetGameInfo(); break; case "BotDomination": gameInfoStr = BotDomination(Level.Game).GetGameInfo(); break; case "BotCTF": gameInfoStr = BotCTF(Level.Game).GetGameInfo(); break; } levelName = string(Level); i = InStr(Caps(levelName), ".LEVELINFO"); if(i != -1) levelName = Left(levelName, i); SendLine("NFO" $ib$as$ "Gametype" $ib$ Parent.gameClass $ae$ib$as$ "Level" $ib$ levelName $ae$ gameInfoStr); gotoState('monitoring','Running'); } //Closed on other end event Closed() { Destroy(); } //Recieve info - parse into lines and call RecievedLine event ReceivedText( string Text ) { local int i; local string S; if(bDebug) log("Recieved - "$Text); ReceivedData = ReceivedData $ Text; // remove a LF which arrived in a new packet // and thus didn't get cleaned up by the code below if(Left(ReceivedData, 1) == Chr(10)) ReceivedData = Mid(ReceivedData, 1); i = InStr(ReceivedData, Chr(13)); while(i != -1) { S = Left(ReceivedData, i); i++; // check for any LF following the CR. if(Mid(ReceivedData, i, 1) == Chr(10)) i++; ReceivedData = Mid(ReceivedData, i); ReceivedLine(S); if(LinkState != STATE_Connected) return; i = InStr(ReceivedData, Chr(13)); } } //Here is where we handle incoming commands /* Commands expected to look like: runto {Argument value} {Arg value}... Currently hard coded to take no more than 9 args Command type and arguments can be any length, but first space terminates the name. Values can have spaces or any other kind of character. */ function ReceivedLine(string S) { local string cmdType, argBody, rem; local int endloc, wordsplit, attrNum; local name curBotState; if(bDebug) log(S); wordsplit = InStr(S,ib); if( wordsplit == -1) wordsplit = Len(S); cmdType = left(S,wordsplit); rem = mid(S,InStr(S,as)); attrNum = 0; //iterate through attr/val pairs, storring them in the //parallel arrays RecievedArgs and RecievedVals while(attrNum < 9 && rem != "") { endloc = InStr(rem,ae); argBody = mid(rem,1,(endloc - 1)); wordsplit = InStr(argBody,ib); RecievedArgs[attrNum] = left(argBody,wordsplit); RecievedVals[attrNum] = mid(argBody,(wordsplit + 1)); rem = mid(rem,1); //advance rem = mid(rem,InStr(rem,as)); attrNum++; } cmdType = Caps(cmdType); ProcessAction(cmdType); } function string GetArgVal(string argName) { local string argValue; local int i; while (i < 9 && RecievedArgs[i] != "") { if (RecievedArgs[i] ~= argName) return RecievedVals[i]; i++; } return ""; } function ProcessAction(string cmdType) { local int i; local vector v, v2; local bool boolResult; local string target, rotTarg, id, outBuf, focusTarg; local rotator r; if(bDebug) log("comandType:"@cmdType); switch(cmdType) { case "PAUSE": if (bAllowPause) Level.Pauser="vizClient"; break; case "UNPAUSE": if (bAllowPause) Level.Pauser=""; break; } } //Send a line to the client function SendLine(string Text, optional bool bNoCRLF) { if(bDebug) log(" Sending: "$Text); if(bNoCRLF) SendText(Text); else SendText(Text$Chr(13)$Chr(10)); } //Concat two strings togeather with our list bookends function string MakeItem(string first, string second) { return (as$first$ib$second$ae); } // iterate through objects and send appropriate messages function checkGame() { local Inventory I; local Pawn P; local string plrString; local NavigationPoint N; local CTFFlag C; local bool isVisible, sendUpdate; local int repeat, temp; local string navType, outstring; SendLine("BEG" $ib$as$ "Time" $ib$ Level.TimeSeconds $ae); //no clean way to do this since gametypes are not derived from //a common ancestor that has AddRemoteBot switch(Parent.gameClass) { case "BotTeamGamePlus": sendLine( BotTeamGamePlus(Level.Game).GetGameStatus() ); break; case "BotDeathMatchPlus": sendLine( BotDeathMatchPlus(Level.Game).GetGameStatus() ); break; case "BotDomination": sendLine( BotDomination(Level.Game).GetGameStatus() ); break; case "BotCTF": sendLine( BotCTF(Level.Game).GetGameStatus(none) ); break; } for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if( !P.bHidden ) { plrString = "PLR" $ib$as$ "Id" $ib$ P $ae$ib$as$ "Rotation" $ib$ P.Rotation $ae$ib$as$ "Location" $ib$ P.Location $ae$ib$as$ "Team" $ib$ P.PlayerReplicationInfo.Team $ae$ib$as$ "Name" $ib$ P.PlayerReplicationInfo.PlayerName $ae$ib$as$ "Weapon" $ib$ P.Weapon.Class $ae; if( P.bFire != 0 ) plrString = plrString $ib$as$ "Firing" $ib$ "1" $ae; else if( P.bAltFire != 0 ) plrString = plrString $ib$as$ "AltFiring" $ib$ "2" $ae; else plrString = plrString $ib$as$ "AltFiring" $ib$ "0" $ae; sendLine(plrString); } } for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) { if(N.IsA('ControlPoint')) { if( ControlPoint(N).ControllingTeam == none ) temp = 255; else temp = ControlPoint(N).ControllingTeam.TeamIndex; SendLine("DOM" $ib$as$ "Id" $ib$ N $ae$ib$as$ "Location" $ib$ N.Location $ae$ib$as$ "Controller" $ib$ temp $ae); } else if(!sentNavs) { //only send Navs once SendLine("NAV" $ib$as$ "Id" $ib$ N $ae$ib$as$ "Location" $ib$ N.Location $ae); } } sentNavs = true; foreach AllActors (class'Inventory', I) { if( I.GetStateName() == 'Pickup' && !I.bHidden ) { SendLine("INV" $ib$as$ "Id" $ib$ I $ae$ib$as$ "Location" $ib$ I.Location $ae); } } foreach AllActors (class'CTFFlag', C) { outstring = "FLG" $ib$as$ "Id" $ib$ C $ae$ib$as$ "Team" $ib$ C.Team $ae$ib$as$ "State" $ib$ C.GetStateName() $ae; //when a flag is held its location is not updated by engine =( if( C.GetStateName() == 'Held') outstring = outstring $ib$as$ "Location" $ib$ C.Holder.Location $ae$ib$as$ "Holder" $ib$ C.Holder $ae; else outstring = outstring $ib$as$ "Location" $ib$ C.Location $ae; SendLine(outstring); } SendLine("END" $ib$as$ "Time" $ib$ Level.TimeSeconds $ae); } //fire right up into the loop for sending updates auto state monitoring { Begin: Running: if( Level.Pauser == "" ) checkGame(); sleep(updateTime); goto 'Running'; } Jclass VizServer expands TcpLink config(BotAPI); var config int ListenPort; var config int MaxConnections; var string gameClass; var bool bBound; var config bool bDebug; var int ConnectionCount; //shouldn't happen event ReceivedText( string Text ) { if(bDebug) log("RecievedText in VizServer - "$Text); } function BeginPlay() { Super.BeginPlay(); if(!bBound) { BindPort( ListenPort ); if(bDebug) log("VizServer bound to port "$ListenPort); Listen(); bBound = true; } } //should never happen - accepted connections should be forwarded to a botconnection event Accepted() { if(bDebug) log("Accepted connection in VizServer"); } //called everytime a new botconnection is spawned event GainedChild( Actor C ) { Super.GainedChild(C); ConnectionCount++; //BotConnection(C).Parent = self; // if too many connections, close down listen. if(MaxConnections > 0 && ConnectionCount > MaxConnections && LinkState == STATE_Listening) { if(bDebug) Log("VizServer: Too many connections - closing down Listen."); Close(); } } event LostChild( Actor C ) { Super.LostChild(C); ConnectionCount--; // if closed due to too many connections, start listening again. if(ConnectionCount <= MaxConnections && LinkState != STATE_Listening) { if(bDebug) Log("VizServer: Listening again - connections have been closed."); Listen(); } } FH -oy$$v.TH Brv*Failed to spawn remote bot.*v=V{G v=VT :v'v-'w* &v%w* &v%]v } BCm#~- % B%C%q%p%m&mmqBmqmmpCmpmmY-''qp&w*- :Ba/!a/!i.)!wi*i%iH*!Ui qpiC$'-(|w*e-a/!a/!$.![S..erS*S-S-3:S:.*\.C g"!8"gda^Z q//Scrollable frame for RemoteUTBotConfigClient class RemoteUTBotConfigSClient extends UWindowScrollingDialogClient; function Created() { ClientClass = class'RemoteUTBotConfigClient'; FixedAreaClass = None; Super.Created(); } vNrPP/$Z 2cQ//Remotebot version of the bot configuration menu - ensures singleplayer // and net games both set minimal bots in the same way. class RemoteUTBotConfigClient extends UMenuBotConfigBase; // Botconfig var Class BotConfig; var UWindowCheckbox BalanceTeamsCheck; var localized string BalanceTeamsText; var localized string BalanceTeamsHelp; var UWindowCheckbox DumbDownCheck; var localized string DumbDownText; var localized string DumbDownHelp; var localized string MinPlayersText; var localized string MinPlayersHelp; function Created() { local int ControlWidth, ControlLeft, ControlRight; local int CenterWidth, CenterPos, ButtonWidth, ButtonLeft; Super.Created(); ControlWidth = WinWidth/2.5; ControlLeft = (WinWidth/2 - ControlWidth)/2; ControlRight = WinWidth/2 + ControlLeft; CenterWidth = (WinWidth/4)*3; CenterPos = (WinWidth - CenterWidth)/2; NumBotsEdit.SetText(MinPlayersText); NumBotsEdit.SetHelpText(MinPlayersHelp); if(class(BotmatchParent.GameClass) != None) { // Balance Teams BalanceTeamsCheck = UWindowCheckbox(CreateControl(class'UWindowCheckbox', ControlLeft, ControlOffset, ControlWidth, 1)); BalanceTeamsCheck.SetText(BalanceTeamsText); BalanceTeamsCheck.SetHelpText(BalanceTeamsHelp); BalanceTeamsCheck.SetFont(F_Normal); BalanceTeamsCheck.Align = TA_Right; if(class(BotmatchParent.GameClass) != None) { DumbDownCheck = UWindowCheckbox(CreateControl(class'UWindowCheckbox', ControlRight, ControlOffset, ControlWidth, 1)); DumbDownCheck.SetText(DumbDownText); DumbDownCheck.SetHelpText(DumbDownHelp); DumbDownCheck.SetFont(F_Normal); DumbDownCheck.Align = TA_Right; } ControlOffset += 25; } } function BeforePaint(Canvas C, float X, float Y) { local int ControlWidth, ControlLeft, ControlRight; local int CenterWidth, CenterPos, ButtonWidth, ButtonLeft; Super.BeforePaint(C, X, Y); ControlWidth = WinWidth/2.5; ControlLeft = (WinWidth/2 - ControlWidth)/2; ControlRight = WinWidth/2 + ControlLeft; CenterWidth = (WinWidth/4)*3; CenterPos = (WinWidth - CenterWidth)/2; if(BalanceTeamsCheck != None) { BalanceTeamsCheck.SetSize(ControlWidth + 10, 1); BalanceTeamsCheck.WinLeft = ControlLeft - 5; } if(DumbDownCheck != None) { DumbDownCheck.SetSize(ControlWidth + 10, 1); DumbDownCheck.WinLeft = ControlRight - 5; } } function AutoAdjustChecked() { BotConfig.Default.bAdjustSkill = AutoAdjustCheck.bChecked; BotConfig.static.StaticSaveConfig(); } function RandomChecked() { BotConfig.Default.bRandomOrder = RandomCheck.bChecked; BotConfig.static.StaticSaveConfig(); } function ConfigureIndivBots() { if(int(NumBotsEdit.GetValue()) == 0) MessageBox(AtLeastOneBotTitle, AtLeastOneBotText, MB_OK, MR_OK, MR_OK); else GetParent(class'UWindowFramedWindow').ShowModal(Root.CreateWindow(class'UTMenu.UTConfigIndivBotsWindow', 100, 100, 200, 200, Self)); } // replaces UMenuBotConfigClientWindow's version function LoadCurrentValues() { local int i; BotConfig = class'DeathMatchPlus'.default.BotConfigType; for(i=0;i<8;i++) Skills[i] = BotConfig.default.Skills[i]; BaseCombo.SetSelectedIndex(Min(BotConfig.default.Difficulty, 7)); TauntLabel.SetText(SkillTaunts[BaseCombo.GetSelectedIndex()]); AutoAdjustCheck.bChecked = BotConfig.Default.bAdjustSkill; RandomCheck.bChecked = BotConfig.Default.bRandomOrder; NumBotsEdit.SetValue(string(class(BotmatchParent.GameClass).Default.MinPlayers)); if(BalanceTeamsCheck != None) BalanceTeamsCheck.bChecked = class'TeamGamePlus'.Default.bBalanceTeams; if(DumbDownCheck != None) DumbDownCheck.bChecked = !class'Domination'.Default.bDumbDown; } // replaces UMenuBotConfigClientWindow's version function BaseChanged() { TauntLabel.SetText(SkillTaunts[BaseCombo.GetSelectedIndex()]); BotConfig.Default.Difficulty = BaseCombo.GetSelectedIndex(); BotConfig.static.StaticSaveConfig(); } // replaces UMenuBotConfigClientWindow's version function NumBotsChanged() { if (int(NumBotsEdit.GetValue()) > 16) NumBotsEdit.SetValue("16"); class(BotmatchParent.GameClass).default.MinPlayers = int(NumBotsEdit.GetValue()); class(BotmatchParent.GameClass).default.InitialBots = int(NumBotsEdit.GetValue()); BotmatchParent.GameClass.static.StaticSaveConfig(); } function BalanceTeamsChanged() { class'TeamGamePlus'.Default.bBalanceTeams = BalanceTeamsCheck.bChecked; Log("Set BalanceTeams to: "$class'TeamGamePlus'.Default.bBalanceTeams); class'TeamGamePlus'.static.StaticSaveConfig(); } function DumbDownChanged() { class'Domination'.Default.bDumbDown = !DumbDownCheck.bChecked; class'Domination'.static.StaticSaveConfig(); } function SaveConfigs() { Super.SaveConfigs(); } function Notify(UWindowDialogControl C, byte E) { if (!Initialized) return; Super.Notify(C, E); switch(E) { case DE_Change: switch(C) { case BalanceTeamsCheck: BalanceTeamsChanged(); break; case DumbDownCheck: DumbDownChanged(); break; } break; } } KgR&g>ga/!ga/!Yga/!]tga/!    _//============================================================================= // TMale2Bot. //============================================================================= class RemoteTMale2Bot extends RemoteMaleBot; function ForceMeshToExist() { Spawn(class'TMale2'); } FSm RB 6TggFW {q"R"k"|]SoldierSkins.blktu]SoldierSkins.h]Botpack.SelectionMale2L] Male SoldierWS[' .}{-S-S'[{w[*d[a/!@a M[ [ [[' e//============================================================================= // RemoteTMale1Bot. //============================================================================= class RemoteTMale1Bot extends RemoteMaleBot; function ForceMeshToExist() { Spawn(class'TMale1'); } FVn SB 6W'pFW Tpq"k"k"|]CommandoSkins.cmdouMCommandoSkins.h]Botpack.SelectionMale1L]Male Commandox]BotPack.VoiceMaleOneWV Q(YW-MB|I-ypBotServer bound to port S|r-M' h//============================================================================= // TFemale2Bot. //============================================================================= class RemoteTFemale2Bot extends RemoteFemaleBot; DYWB 6Z VqDx {q"R"k"|]SGirlSkins.armyu] SGirlSkins.h]Botpack.SelectionFemale2LMFemale Soldierx]BotPack.VoiceFemaleTwoWg//============================================================================= // TFemale1Bot. //============================================================================= class RemoteTFemale1Bot extends RemoteFemaleBot; function ForceMeshToExist() { Spawn(class'TFemale1'); } i E d q _H} ~1-(-(-(/--(_ D[{ UB 6^Dx q"k"|]FCommandoSkins.cmdou]FCommandoSkins.h]Botpack.SelectionFemale1L]Female Commandox]BotPack.VoiceFemaleOneWL Xx} N coL}-q!; G~u ac' d@@bF `$F Q S Wtd| 8tW e=R+p 250) && (FRand() < 0.75) ) { if ( FRand() < 0.5 ) PlayAnim('Dead1',,0.1); else PlayAnim('Dead11',, 0.1); return; } // check for repeater death if ( (Health > -10) && ((DamageType == 'shot') || (DamageType == 'zapped')) ) { PlayAnim('Dead9',, 0.1); return; } if ( (HitLoc.Z - Location.Z > 0.7 * CollisionHeight) && !Level.Game.bVeryLowGore ) { if ( FRand() < 0.5 ) PlayDecap(); else PlayAnim('Dead7',, 0.1); return; } if ( Region.Zone.bWaterZone || (FRand() < 0.5) ) //then hit in front or back PlayAnim('Dead3',, 0.1); else PlayAnim('Dead8',, 0.1); } function PlayDecap() { local carcass carc; PlayAnim('Dead4',, 0.1); if ( Level.NetMode != NM_Client ) { carc = Spawn(class 'UT_HeadMale',,, Location + CollisionHeight * vect(0,0,0.8), Rotation + rot(3000,0,16384) ); if (carc != None) { carc.Initfor(self); carc.Velocity = Velocity + VSize(Velocity) * VRand(); carc.Velocity.Z = FMax(carc.Velocity.Z, Velocity.Z); } } } function PlayGutHit(float tweentime) { if ( (AnimSequence == 'GutHit') || (AnimSequence == 'Dead2') ) { if (FRand() < 0.5) TweenAnim('LeftHit', tweentime); else TweenAnim('RightHit', tweentime); } else if ( FRand() < 0.6 ) TweenAnim('GutHit', tweentime); else TweenAnim('Dead8', tweentime); } function PlayHeadHit(float tweentime) { if ( (AnimSequence == 'HeadHit') || (AnimSequence == 'Dead7') ) TweenAnim('GutHit', tweentime); else if ( FRand() < 0.6 ) TweenAnim('HeadHit', tweentime); else TweenAnim('Dead7', tweentime); } function PlayLeftHit(float tweentime) { if ( (AnimSequence == 'LeftHit') || (AnimSequence == 'Dead9') ) TweenAnim('GutHit', tweentime); else if ( FRand() < 0.6 ) TweenAnim('LeftHit', tweentime); else TweenAnim('Dead9', tweentime); } function PlayRightHit(float tweentime) { if ( (AnimSequence == 'RightHit') || (AnimSequence == 'Dead1') ) TweenAnim('GutHit', tweentime); else if ( FRand() < 0.6 ) TweenAnim('RightHit', tweentime); else TweenAnim('Dead1', tweentime); } K #d+,-:#,(:#,##:#r%rrE*%Er}rErr-_&YhwY*QYa/!Ya/!hYYwY*wY*8:YE#=,::Y\\:%:E#=,:,:%:E#=,:,:, ::}Q#a/!#=,0w* #Ow* #'#a/! #=:w* #w* #':#:-(#a/!.#*K:I:#'wE*EI}#'( C//============================================================================= // RemoteHumanBot. //============================================================================= class RemoteHumanBot extends RemoteBot abstract; //----------------------------------------------------------------------------- // Sound functions //----------------------------------------------------------------------------- // Animation functions function PlayTurning() { BaseEyeHeight = Default.BaseEyeHeight; if ( (Weapon == None) || (Weapon.Mass < 20) ) PlayAnim('TurnSM', 0.3, 0.3); else PlayAnim('TurnLG', 0.3, 0.3); } function PlayVictoryDance() { PlayAnim('Victory1', 0.7); } function PlayWaving() { PlayAnim('Wave', 0.7, 0.2); } function TweenToWalking(float tweentime) { if ( Physics == PHYS_Swimming ) { if ( (vector(Rotation) Dot Acceleration) > 0 ) TweenToSwimming(tweentime); else TweenToWaiting(tweentime); } BaseEyeHeight = Default.BaseEyeHeight; if (Weapon == None) TweenAnim('Walk', tweentime); else if ( Weapon.bPointing ) { if (Weapon.Mass < 20) TweenAnim('WalkSMFR', tweentime); else TweenAnim('WalkLGFR', tweentime); } else { if (Weapon.Mass < 20) TweenAnim('WalkSM', tweentime); else TweenAnim('WalkLG', tweentime); } } function TweenToRunning(float tweentime) { local name newAnim; if ( Physics == PHYS_Swimming ) { if ( (vector(Rotation) Dot Acceleration) > 0 ) TweenToSwimming(tweentime); else TweenToWaiting(tweentime); return; } BaseEyeHeight = Default.BaseEyeHeight; if (Weapon == None) newAnim = 'RunSM'; else if ( Weapon.bPointing ) { if (Weapon.Mass < 20) newAnim = 'RunSMFR'; else newAnim = 'RunLGFR'; } else { if (Weapon.Mass < 20) newAnim = 'RunSM'; else newAnim = 'RunLG'; } if ( (newAnim == AnimSequence) && (Acceleration != vect(0,0,0)) && IsAnimating() ) return; TweenAnim(newAnim, tweentime); } function PlayWalking() { if ( Physics == PHYS_Swimming ) { if ( (vector(Rotation) Dot Acceleration) > 0 ) PlaySwimming(); else PlayWaiting(); return; } BaseEyeHeight = Default.BaseEyeHeight; if (Weapon == None) LoopAnim('Walk'); else if ( Weapon.bPointing ) { if (Weapon.Mass < 20) LoopAnim('WalkSMFR'); else LoopAnim('WalkLGFR'); } else { if (Weapon.Mass < 20) LoopAnim('WalkSM'); else LoopAnim('WalkLG'); } } function PlayRunning() { local float strafeMag; local vector Focus2D, Loc2D, Dest2D; local vector lookDir, moveDir, Y; local name NewAnim; if ( Physics == PHYS_Swimming ) { if ( (vector(Rotation) Dot Acceleration) > 0 ) PlaySwimming(); else PlayWaiting(); return; } BaseEyeHeight = Default.BaseEyeHeight; if ( bAdvancedTactics && !bNoTact ) { if ( bTacticalDir ) LoopAnim('StrafeL'); else LoopAnim('StrafeR'); return; } else if ( Focus != Destination ) { // check for strafe or backup Focus2D = Focus; Focus2D.Z = 0; Loc2D = Location; Loc2D.Z = 0; Dest2D = Destination; Dest2D.Z = 0; lookDir = Normal(Focus2D - Loc2D); moveDir = Normal(Dest2D - Loc2D); strafeMag = lookDir dot moveDir; if ( strafeMag < 0.75 ) { if ( strafeMag < -0.75 ) LoopAnim('BackRun'); else { Y = (lookDir Cross vect(0,0,1)); if ((Y Dot (Dest2D - Loc2D)) > 0) LoopAnim('StrafeL'); else LoopAnim('StrafeR'); } return; } } if (Weapon == None) newAnim = 'RunSM'; else if ( Weapon.bPointing ) { if (Weapon.Mass < 20) newAnim = 'RunSMFR'; else newAnim = 'RunLGFR'; } else { if (Weapon.Mass < 20) newAnim = 'RunSM'; else newAnim = 'RunLG'; } if ( (newAnim == AnimSequence) && IsAnimating() ) return; LoopAnim(NewAnim); } function PlayRising() { BaseEyeHeight = 0.4 * Default.BaseEyeHeight; TweenAnim('DuckWlkS', 0.7); } function PlayFeignDeath() { local float decision; BaseEyeHeight = 0; if ( decision < 0.33 ) TweenAnim('DeathEnd', 0.5); else if ( decision < 0.67 ) TweenAnim('DeathEnd2', 0.5); else TweenAnim('DeathEnd3', 0.5); } function PlayDying(name DamageType, vector HitLoc) { local vector X,Y,Z, HitVec, HitVec2D; local float dotp; local carcass carc; BaseEyeHeight = Default.BaseEyeHeight; PlayDyingSound(); PlayAnim('Dead3',0.7,0.1); } function PlayGutHit(float tweentime) { if ( (AnimSequence == 'GutHit') || (AnimSequence == 'Dead2') ) { if (FRand() < 0.5) TweenAnim('LeftHit', tweentime); else TweenAnim('RightHit', tweentime); } else if ( FRand() < 0.6 ) TweenAnim('GutHit', tweentime); else TweenAnim('Dead2', tweentime); } function PlayHeadHit(float tweentime) { if ( (AnimSequence == 'HeadHit') || (AnimSequence == 'Dead4') ) TweenAnim('GutHit', tweentime); else if ( FRand() < 0.6 ) TweenAnim('HeadHit', tweentime); else TweenAnim('Dead4', tweentime); } function PlayLeftHit(float tweentime) { if ( (AnimSequence == 'LeftHit') || (AnimSequence == 'Dead3') ) TweenAnim('GutHit', tweentime); else if ( FRand() < 0.6 ) TweenAnim('LeftHit', tweentime); else TweenAnim('Dead3', tweentime); } function PlayRightHit(float tweentime) { if ( (AnimSequence == 'RightHit') || (AnimSequence == 'Dead5') ) TweenAnim('GutHit', tweentime); else if ( FRand() < 0.6 ) TweenAnim('RightHit', tweentime); else TweenAnim('Dead5', tweentime); } function PlayLanded(float impactVel) { impactVel = impactVel/JumpZ; impactVel = 0.1 * impactVel * impactVel; BaseEyeHeight = Default.BaseEyeHeight; if ( impactVel > 0.17 ) PlaySound(LandGrunt, SLOT_Talk, FMin(4, 5 * impactVel),false,1600,FRand()*0.4+0.8); if ( !FootRegion.Zone.bWaterZone && (impactVel > 0.01) ) PlaySound(Land, SLOT_Interact, FClamp(4 * impactVel,0.2,4.5), false,1600, 1.0); if ( (impactVel > 0.06) || (GetAnimGroup(AnimSequence) == 'Jumping') ) { if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('LandSMFR', 0.12); else TweenAnim('LandLGFR', 0.12); } else if ( !IsAnimating() ) { if ( GetAnimGroup(AnimSequence) == 'TakeHit' ) AnimEnd(); else { if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('LandSMFR', 0.12); else TweenAnim('LandLGFR', 0.12); } } } function FastInAir() { local float TweenTime; BaseEyeHeight = 0.7 * Default.BaseEyeHeight; if ( GetAnimGroup(AnimSequence) == 'Jumping' ) { if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('DuckWlkS', 1); else TweenAnim('DuckWlkL', 1); return; } else if ( GetAnimGroup(AnimSequence) == 'Ducking' ) TweenTime = 1; else TweenTime = 0.3; if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('JumpSMFR', TweenTime); else TweenAnim('JumpLGFR', TweenTime); } function PlayInAir() { local float TweenTime; BaseEyeHeight = 0.7 * Default.BaseEyeHeight; if ( GetAnimGroup(AnimSequence) == 'Jumping' ) { if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('DuckWlkS', 2); else TweenAnim('DuckWlkL', 2); return; } else if ( GetAnimGroup(AnimSequence) == 'Ducking' ) TweenTime = 2; else TweenTime = 0.7; if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('JumpSMFR', TweenTime); else TweenAnim('JumpLGFR', TweenTime); } function PlayDodge(bool bDuckLeft) { if ( bDuckLeft ) TweenAnim('DodgeL', 0.25); else TweenAnim('DodgeR', 0.25); } function PlayDuck() { BaseEyeHeight = 0; if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('DuckWlkS', 0.25); else TweenAnim('DuckWlkL', 0.25); } function PlayCrawling() { //log("Play duck"); BaseEyeHeight = 0; if ( (Weapon == None) || (Weapon.Mass < 20) ) LoopAnim('DuckWlkS'); else LoopAnim('DuckWlkL'); } function TweenToWaiting(float tweentime) { if ( Physics == PHYS_Swimming ) { BaseEyeHeight = 0.7 * Default.BaseEyeHeight; if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('TreadSM', tweentime); else TweenAnim('TreadLG', tweentime); } else { BaseEyeHeight = Default.BaseEyeHeight; if ( Enemy != None ) ViewRotation = Rotator(Enemy.Location - Location); else { if ( GetAnimGroup(AnimSequence) == 'Waiting' ) return; ViewRotation.Pitch = 0; } ViewRotation.Pitch = ViewRotation.Pitch & 65535; If ( (ViewRotation.Pitch > RotationRate.Pitch) && (ViewRotation.Pitch < 65536 - RotationRate.Pitch) ) { If (ViewRotation.Pitch < 32768) { if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('AimUpSm', 0.3); else TweenAnim('AimUpLg', 0.3); } else { if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('AimDnSm', 0.3); else TweenAnim('AimDnLg', 0.3); } } else if ( (Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('StillSMFR', tweentime); else TweenAnim('StillFRRP', tweentime); } } function TweenToFighter(float tweentime) { TweenToWaiting(tweentime); } function PlayChallenge() { TweenToWaiting(0.17); } function PlayLookAround() { LoopAnim('Look', 0.3 + 0.7 * FRand(), 0.1); } function PlayWaiting() { local name newAnim; if ( Physics == PHYS_Swimming ) { BaseEyeHeight = 0.7 * Default.BaseEyeHeight; if ( (Weapon == None) || (Weapon.Mass < 20) ) LoopAnim('TreadSM'); else LoopAnim('TreadLG'); } else { BaseEyeHeight = Default.BaseEyeHeight; if ( (Weapon != None) && Weapon.bPointing ) { if ( Weapon.bRapidFire && ((bFire != 0) || (bAltFire != 0)) ) LoopAnim('StillFRRP'); else if ( Weapon.Mass < 20 ) TweenAnim('StillSMFR', 0.3); else TweenAnim('StillFRRP', 0.3); } else { if ( Level.Game.bTeamGame && ((FRand() < 0.04) || ((AnimSequence == 'Chat1') && (FRand() < 0.75))) ) { newAnim = 'Chat1'; } else if ( FRand() < 0.1 ) { if ( (Weapon == None) || (Weapon.Mass < 20) ) PlayAnim('CockGun', 0.5 + 0.5 * FRand(), 0.3); else PlayAnim('CockGunL', 0.5 + 0.5 * FRand(), 0.3); } else { if ( (Weapon == None) || (Weapon.Mass < 20) ) { if ( (FRand() < 0.75) && ((AnimSequence == 'Breath1') || (AnimSequence == 'Breath2')) ) newAnim = AnimSequence; else if ( FRand() < 0.5 ) newAnim = 'Breath1'; else newAnim = 'Breath2'; } else { if ( (FRand() < 0.75) && ((AnimSequence == 'Breath1L') || (AnimSequence == 'Breath2L')) ) newAnim = AnimSequence; else if ( FRand() < 0.5 ) newAnim = 'Breath1L'; else newAnim = 'Breath2L'; } if ( AnimSequence == newAnim ) LoopAnim(newAnim, 0.4 + 0.4 * FRand()); else PlayAnim(newAnim, 0.4 + 0.4 * FRand(), 0.25); } } } } function PlayRecoil(float Rate) { if ( Weapon.bRapidFire ) { if ( (Weapon.AmmoType != None) && (Weapon.AmmoType.AmmoAmount < 2) ) TweenAnim('StillFRRP', 0.1); else if ( !IsAnimating() && (Physics == PHYS_Walking) ) LoopAnim('StillFRRP', 0.02); } else if ( AnimSequence == 'StillSmFr' ) PlayAnim('StillSmFr', Rate, 0.02); else if ( (AnimSequence == 'StillLgFr') || (AnimSequence == 'StillFrRp') ) PlayAnim('StillLgFr', Rate, 0.02); } function PlayFiring() { // switch animation sequence mid-stream if needed if ( GetAnimGroup(AnimSequence) == 'MovingFire' ) return; else if (AnimSequence == 'RunLG') AnimSequence = 'RunLGFR'; else if (AnimSequence == 'RunSM') AnimSequence = 'RunSMFR'; else if (AnimSequence == 'WalkLG') AnimSequence = 'WalkLGFR'; else if (AnimSequence == 'WalkSM') AnimSequence = 'WalkSMFR'; else if ( AnimSequence == 'JumpSMFR' ) TweenAnim('JumpSMFR', 0.03); else if ( AnimSequence == 'JumpLGFR' ) TweenAnim('JumpLGFR', 0.03); else if ( (GetAnimGroup(AnimSequence) == 'Waiting') || (GetAnimGroup(AnimSequence) == 'Gesture') && (AnimSequence != 'TreadLG') && (AnimSequence != 'TreadSM') ) { if ( Weapon.Mass < 20 ) TweenAnim('StillSMFR', 0.02); else if ( !Weapon.bRapidFire || (AnimSequence != 'StillFRRP') ) TweenAnim('StillFRRP', 0.02); else if ( !IsAnimating() ) LoopAnim('StillFRRP'); } } function PlayWeaponSwitch(Weapon NewWeapon) { if ( (Weapon == None) || (Weapon.Mass < 20) ) { if ( (NewWeapon != None) && (NewWeapon.Mass > 20) ) { if ( (AnimSequence == 'RunSM') || (AnimSequence == 'RunSMFR') ) AnimSequence = 'RunLG'; else if ( (AnimSequence == 'WalkSM') || (AnimSequence == 'WalkSMFR') ) AnimSequence = 'WalkLG'; else if ( AnimSequence == 'JumpSMFR' ) AnimSequence = 'JumpLGFR'; else if ( AnimSequence == 'DuckWlkL' ) AnimSequence = 'DuckWlkS'; else if ( AnimSequence == 'StillSMFR' ) AnimSequence = 'StillFRRP'; else if ( AnimSequence == 'AimDnSm' ) AnimSequence = 'AimDnLg'; else if ( AnimSequence == 'AimUpSm' ) AnimSequence = 'AimUpLg'; } } else if ( (NewWeapon == None) || (NewWeapon.Mass < 20) ) { if ( (AnimSequence == 'RunLG') || (AnimSequence == 'RunLGFR') ) AnimSequence = 'RunSM'; else if ( (AnimSequence == 'WalkLG') || (AnimSequence == 'WalkLGFR') ) AnimSequence = 'WalkSM'; else if ( AnimSequence == 'JumpLGFR' ) AnimSequence = 'JumpSMFR'; else if ( AnimSequence == 'DuckWlkS' ) AnimSequence = 'DuckWlkL'; else if (AnimSequence == 'StillFRRP') AnimSequence = 'StillSMFR'; else if ( AnimSequence == 'AimDnLg' ) AnimSequence = 'AimDnSm'; else if ( AnimSequence == 'AimUpLg' ) AnimSequence = 'AimUpSm'; } } function PlaySwimming() { BaseEyeHeight = 0.7 * Default.BaseEyeHeight; if ((Weapon == None) || (Weapon.Mass < 20) ) LoopAnim('SwimSM'); else LoopAnim('SwimLG'); } function TweenToSwimming(float tweentime) { BaseEyeHeight = 0.7 * Default.BaseEyeHeight; if ((Weapon == None) || (Weapon.Mass < 20) ) TweenAnim('SwimSM',tweentime); else TweenAnim('SwimLG',tweentime); } State ImpactJumping { function PlayWaiting() { TweenAnim('AimDnLg', 0.3); } } hmaL)9N%1N,:NJ&NN NZ)//============================================================================= // FemaleBotPlus. //============================================================================= class RemoteFemaleBot extends RemoteHumanBot abstract; function PlayRightHit(float tweentime) { if ( AnimSequence == 'RightHit' ) TweenAnim('GutHit', tweentime); else TweenAnim('RightHit', tweentime); } function PlayChallenge() { TweenToWaiting(0.17); } function PlayVictoryDance() { local float decision; decision = FRand(); if ( decision < 0.25 ) PlayAnim('Victory1',0.7, 0.2); else if ( decision < 0.5 ) PlayAnim('Thrust',0.7, 0.2); else if ( decision < 0.75 ) PlayAnim('Taunt1',0.7, 0.2); else TweenAnim('Taunt1', 0.2); } function PlayDying(name DamageType, vector HitLoc) { local carcass carc; BaseEyeHeight = Default.BaseEyeHeight; PlayDyingSound(); if ( DamageType == 'Suicided' ) { PlayAnim('Dead3',, 0.1); return; } // check for head hit if ( (DamageType == 'Decapitated') && !Level.Game.bVeryLowGore ) { PlayDecap(); return; } if ( FRand() < 0.15 ) { PlayAnim('Dead7',,0.1); return; } // check for big hit if ( (Velocity.Z > 250) && (FRand() < 0.75) ) { if ( (HitLoc.Z < Location.Z) && !Level.Game.bVeryLowGore && (FRand() < 0.6) ) { PlayAnim('Dead5',,0.05); if ( Level.NetMode != NM_Client ) { carc = Spawn(class 'UT_FemaleFoot',,, Location - CollisionHeight * vect(0,0,0.5)); if (carc != None) { carc.Initfor(self); carc.Velocity = Velocity + VSize(Velocity) * VRand(); carc.Velocity.Z = FMax(carc.Velocity.Z, Velocity.Z); } } } else PlayAnim('Dead2',, 0.1); return; } // check for repeater death if ( (Health > -10) && ((DamageType == 'shot') || (DamageType == 'zapped')) ) { PlayAnim('Dead9',, 0.1); return; } if ( (HitLoc.Z - Location.Z > 0.7 * CollisionHeight) && !Level.Game.bVeryLowGore ) { if ( FRand() < 0.5 ) PlayDecap(); else PlayAnim('Dead3',, 0.1); return; } //then hit in front or back if ( FRand() < 0.5 ) PlayAnim('Dead4',, 0.1); else PlayAnim('Dead1',, 0.1); } function PlayDecap() { local carcass carc; PlayAnim('Dead6',, 0.1); if ( Level.NetMode != NM_Client ) { carc = Spawn(class 'UT_HeadFemale',,, Location + CollisionHeight * vect(0,0,0.8), Rotation + rot(3000,0,16384) ); if (carc != None) { carc.Initfor(self); carc.Velocity = Velocity + VSize(Velocity) * VRand(); carc.Velocity.Z = FMax(carc.Velocity.Z, Velocity.Z); } } } lC YVC v  Z qa/0q[H% [H ::$-oVizServer: Too many connections - closing down Listen.W n D* D //============================================================================= // RemoteBotInfo. //============================================================================= class RemoteBotInfo extends Info config(BotAPI); var() string VoiceType[32]; var() string BotFaces[32]; var() config byte Difficulty; var() config string BotNames[32]; var() int BotTeams[32]; var() config float BotAccuracy; var() config float Alertness; var byte ConfigUsed[32]; var() string BotClasses[32]; var() string BotSkins[32]; function PreBeginPlay() { //DON'T Call parent prebeginplay } function PostBeginPlay() { local String NextBotClass, NextBotDesc; Super.PostBeginPlay(); } function int GetBotTeam(int BotN) { return BotTeams[BotN]; } function CHIndividualize(RemoteBot NewBot, int num) { local int n; n = num % 32; // Set bot's skin NewBot.Static.SetMultiSkin(NewBot, BotSkins[n], BotFaces[n], BotTeams[n]); // Set bot's name. if ( (BotNames[n] == "") || (ConfigUsed[n] == 1) ) BotNames[n] = "RemoteBot"; Level.Game.ChangeName( NewBot, BotNames[n], false ); if ( BotNames[n] != NewBot.PlayerReplicationInfo.PlayerName ) Level.Game.ChangeName( NewBot, ("RemoteBot"$NewBot), false); ConfigUsed[n] = 1; // adjust bot skill NewBot.InitializeSkill(Difficulty); NewBot.Accuracy = BotAccuracy; NewBot.BaseAlertness = Alertness; if ( VoiceType[n] != "" && VoiceType[n] != "None" ) NewBot.PlayerReplicationInfo.VoiceType = class(DynamicLoadObject(VoiceType[n], class'Class')); if(NewBot.PlayerReplicationInfo.VoiceType == None) NewBot.PlayerReplicationInfo.VoiceType = class(DynamicLoadObject(NewBot.VoiceType, class'Class')); } function int ChooseBotInfo() { local int n; n = 0; while ( (n < 31) && (ConfigUsed[n] == 1) ) n++; return n; } function class CHGetBotClass(int n) { return class( DynamicLoadObject(BotClasses[n], class'Class') ); } N//============================================================================= // RemoteBot. // Basedon Bot class //============================================================================= class RemoteBot expands Bot abstract config(BotAPI); var config bool bDebug; //maybe link to bot's periphreal vision? UT bots need much less of an arc though //like Pawn's PeriphrealVision, this value should be the cosine of the limits //of visual field. (i.e. 0.707 = 45 degrees to each side, or a 90* arc.) var config float remoteVisionLimit; //The socket to the agent var BotConnection myConnection; //The three remote vars compliment the my vars right below. The only one //that ever needs to be duplicated is RemoteEnemy and myTarget //just need RemoteDestination || myDestination and RFocus || myFocus //Who the remote bot is trying to shoot at. Used by the aiming code. var Actor RemoteEnemy; //Thing the remote bot is trying to move to. var Actor RemoteDestination; //Thing the remote bot is looking at. var Actor RemoteFocus; //The spot the bot is shooting at var vector myTarget; //The spot the bot is moving to var vector myDestination; //The spot the bot is looking at var vector myFocus; // time that last sent a WAL message var float lastWallHitTime; // time that last sent a BMP message var float lastBumpTime; // delimeters for strings sent to clients. set to match those of myConnection // as = identifies the start of an attribute var string as; // ae = attribute end var string ae; // ib = item break var string ib; // called when using movetoward with bAdvancedTactics true to temporarily modify destination event AlterDestination(); // Mover has notifies pawn that pawn is underneath it function UnderLift(Mover M) { // SENDMESSAGE // !!! possible new message } //Take a wild guess function StartMatch() { // SENDMESSAGE // !!! possible new message } //Called from weapon code when out of ammo or some such //Don't call from local - weapon won't stop until ticked function StopFiring() { bFire = 0; bAltFire = 0; } //Use from local code - stops firing and ticks weapon to let it stop function HaltFiring() { StopFiring(); if ( Weapon != None ) Weapon.Tick(0.001); } //Change to what the bot is standing on singular event BaseChange() { local actor HitActor; local vector HitNormal, HitLocation; // !!! Can't handle shootable floors /* if ( Mover(Base) != None ) { // handle shootable secret floors if ( Mover(Base).bDamageTriggered && !Mover(Base).bOpening && (MoveTarget != None) ) { HitActor = Trace(HitLocation, HitNormal, MoveTarget.Location, Location, true); if ( HitActor == Base ) { Target = Base; bShootSpecial = true; FireWeapon(); bFire = 0; bAltFire = 0; Base.Trigger(Base, Self); bShootSpecial = false; } } } else */ Super(Pawn).BaseChange(); // !!! possible SENDMESSAGE } //Called right before bot falls off something //If bot running, set bCanJump to true - let him fall //if walking, won't fall event MayFall() { local bool bFall; bFall = !bIsWalking; if(!bfall) { GotoState('Startup', 'Begin'); } myConnection.SendLine("FAL" $ib$as$ "Fell" $ib$ bFall $ae$ib$as$ "Location" $ib$ Location $ae); bCanJump = bFall; } function float GetSpeed() { if(bIsWalking) { return WalkingSpeed; } else { return 1.0; } } //can be autocalled when bot is shot by team mate function YellAt(Pawn Moron); //called when get new item function bool AddInventory( inventory NewItem ) { Super(Pawn).AddInventory(NewItem); myConnection.SendLine("AIN" $ib$as$ "Id" $ib$ NewItem $ae$ib$as$ "Class" $ib$ NewItem.Class $ae); } // !!! need functions to send arbitrary string messages //functions to send tokenized messages function SendTeamMessage(PlayerReplicationInfo Recipient, name MessageType, byte MessageID, float Wait) { //log(self@"Send message"@MessageType@MessageID@"at"@Level.TimeSeconds); if ( (MessageType == OldMessageType) && (MessageID == OldMessageID) && (Level.TimeSeconds - OldMessageTime < Wait) ) return; //log("Passed filter"); OldMessageID = MessageID; OldMessageType = MessageType; SendVoiceMessage(PlayerReplicationInfo, Recipient, MessageType, MessageID, 'TEAM'); } function SendGlobalMessage(PlayerReplicationInfo Recipient, name MessageType, byte MessageID, float Wait) { //log(self@"Send message"@MessageType@MessageID@"at"@Level.TimeSeconds); if ( (MessageType == OldMessageType) && (MessageID == OldMessageID) && (Level.TimeSeconds - OldMessageTime < Wait) ) return; //log("Passed filter"); OldMessageID = MessageID; OldMessageType = MessageType; SendVoiceMessage(PlayerReplicationInfo, Recipient, MessageType, MessageID, 'GLOBAL'); } //events for recieving arbitrary string messages event ClientMessage( coerce string S, optional name Type, optional bool bBeep ) { myConnection.SendLine("VMS" $ib$as$ "String" $ib$ S $ae); } event TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type, optional bool bBeep ) { myConnection.SendLine("VMT" $ib$as$ "String" $ib$ S $ae); } //events for recieving tokenized voice message function BotVoiceMessage(name messagetype, byte messageID, Pawn Sender) { if (Sender.PlayerReplicationInfo.Team != PlayerReplicationInfo.Team) return; myConnection.SendLine("VMG" $ib$as$ "Sender" $ib$ Sender $ae$ib$as$ "Type" $ib$ messagetype $ae$ib$as$ "Id" $ib$ messageID $ae); } //other code may try to call this. make sure nada happens //!!! need to change - make sure orders are actually recorded somewhere // for reference function SetOrders(name NewOrders, Pawn OrderGiver, optional bool bNoAck); /* // !!! Allow for disabling of autoswitch??? function bool SwitchToBestWeapon() { local float rating; local int usealt, favalt; local inventory MyFav; if ( Inventory == None ) return false; PendingWeapon = Inventory.RecommendWeapon(rating, usealt); if ( PendingWeapon == None ) return false; if ( (FavoriteWeapon != None) && (PendingWeapon.class != FavoriteWeapon) ) { MyFav = FindInventoryType(FavoriteWeapon); if ( (MyFav != None) && (Weapon(MyFav).RateSelf(favalt) + 0.22 > PendingWeapon.RateSelf(usealt)) ) { usealt = favalt; PendingWeapon = Weapon(MyFav); } } if ( Weapon == None ) ChangedWeapon(); else if ( Weapon != PendingWeapon ) Weapon.PutDown(); return (usealt > 0); } */ //events that are called when head, feet or whole bot changes zones //e.g. air to water or lava //only way to tell if underwater until drowning damage starts function FootZoneChange(ZoneInfo newFootZone) { Super.FootZoneChange(newFootZone); myConnection.SendLine("ZCF" $ib$as$ "Id" $ib$ newFootZone $ae); } function HeadZoneChange(ZoneInfo newHeadZone) { Super.HeadZoneChange(newHeadZone); myConnection.SendLine("ZCH" $ib$as$ "Id" $ib$ newHeadZone $ae); } function ZoneChange(ZoneInfo newZone) { Super.ZoneChange(newZone); myConnection.SendLine("ZCB" $ib$as$ "Id" $ib$ newZone $ae); } //may want to hack into this for vision limits. //used by existing bots to change fov based on activity. function SetPeripheralVision() { if ( bNovice ) PeripheralVision = 0.7; else if ( Skill == 3 ) PeripheralVision = -0.2; else PeripheralVision = 0.65 - 0.33 * skill; PeripheralVision = FMin(PeripheralVision - BaseAlertness, 0.9); SightRadius = Default.SightRadius; } //overriden to avoid bot version which can goto state 'findair' function PainTimer() { local float depth; if (Health <= 0) return; if (FootRegion.Zone.bPainZone) Super(Pawn).PainTimer(); else if (HeadRegion.Zone.bWaterZone) { if (bDrowning) self.TakeDamage(5, None, Location + CollisionHeight * vect(0,0,0.5), vect(0,0,0), 'Drowned'); if (Health > 0) PainTime = 2.0; } } //Called when weapon is switched - may happen automatically function ChangedWeapon() { local int usealt; if ( Weapon == PendingWeapon ) { if ( Weapon == None ) SwitchToBestWeapon(); else if ( Weapon.GetStateName() == 'DownWeapon' ) Weapon.GotoState('Idle'); PendingWeapon = None; } else Super(Pawn).ChangedWeapon(); if ( Weapon != None ) { if (bFire > 0) { bAltFire = 0; bFire = 1; Weapon.Fire(1.0); } else if (bAltFire > 0) { bAltFire = 0; bFire = 1; Weapon.AltFire(1.0); } Weapon.SetHand(0); // Weapon.FireOffset.Y = 0; } // !!! use or just make people get from status update myConnection.SendLine("CWP" $ib$as$ "Id" $ib$ Weapon $ae$ib$as$ "Class" $ib$ Weapon.Class $ae); } // called from pathnodes that unitelligent creatures are supposed to avoid function FearThisSpot(Actor aSpot); //called on hitting a wall event HitWall( vector HitNormal, actor HitWall ) { if ( Level.TimeSeconds - 0.5 >= lastWallHitTime ) { myConnection.SendLine("WAL" $ib$as$ "Id" $ib$ HitWall $ae$ib$as$ "Normal" $ib$ HitNormal $ae$ib$as$ "Location" $ib$ Location $ae); lastWallHitTime = Level.TimeSeconds; } } //called on collisions with other actors function Bump(actor Other) { local vector VelDir, OtherDir; local float speed, dist; if ( TimerRate <= 0 ) setTimer(1.0, false); speed = VSize(Velocity); if ( speed > 10 ) { VelDir = Velocity/speed; VelDir.Z = 0; OtherDir = Other.Location - Location; OtherDir.Z = 0; OtherDir = Normal(OtherDir); if ( (VelDir Dot OtherDir) > 0.8 ) { Velocity.X = VelDir.Y; Velocity.Y = -1 * VelDir.X; Velocity *= FMax(speed, 280); } } if ( Level.TimeSeconds - 0.5 >= lastBumpTime ) { myConnection.SendLine("BMP" $ib$as$ "Id" $ib$ Other $ae$ib$as$ "Location" $ib$ Other.Location $ae); lastBumpTime = Level.TimeSeconds; } // Need to disable bumping ??? Disable('Bump'); } function SetFall() { //SENDMESSAGE if (Enemy != None) { TweenToFalling(); NextAnim = AnimSequence; GotoState('FallingState'); } } function LongFall() { // SENDMESSAGE ??? } //called when someone picksup a nearby object WORKING???? function HearPickup(Pawn Other) { myConnection.SendLine("HRP" $ib$as$ "Rotation" $ib$ rotator(Location - Other.Location) $ae); } //called when sound is made function HearNoise(float Loudness, Actor NoiseMaker) { myConnection.SendLine("HRN" $ib$as$ "SourceClass" $ib$ NoiseMaker.Class $ae$ib$as$ "Rotation" $ib$ rotator(Location - NoiseMaker.Location) $ae); } //called periodicaly for each player in view function SeePlayer(Actor SeenPlayer) { /* myConnection.SendLine("SEE" $ib$as$ "Id" $ib$ SeenPlayer $ae$ib$as$ "Rotation" $ib$ SeenPlayer.Rotation $ae$ib$as$ "Location" $ib$ SeenPlayer.Location $ae$ib$as$ "Velocity" $ib$ SeenPlayer.Velocity $ae$ib$as$ "Name" $ib$ Pawn(SeenPlayer).PlayerReplicationInfo.PlayerName $ae$ib$as$ "Team" $ib$ Pawn(SeenPlayer).PlayerReplicationInfo.Team $ae$ib$as$ "Reachable" $ib$ actorReachable(SeenPlayer) $ae$ib$as$ "Weapon" $ib$ Pawn(SeenPlayer).Weapon.Class $ae); */ } /* FindBestPathToward() assumes the desired destination is not directly reachable, given the creature's intelligence, it tries to set Destination to the location of the best waypoint, and returns true if successful */ /* function bool FindBestPathToward(actor desired, bool bClearPaths) { local Actor path; local bool success; if ( specialGoal != None) desired = specialGoal; path = None; path = FindPathToward(desired,,bClearPaths); success = (path != None); if (success) { MoveTarget = path; Destination = path.Location; } return success; } */ /* NearWall() returns true if there is a nearby barrier at eyeheight, and changes Focus to a suggested value */ //Potentially usefull /* function bool NearWall(float walldist) { local actor HitActor; local vector HitLocation, HitNormal, ViewSpot, ViewDist, LookDir; LookDir = vector(Rotation); ViewSpot = Location + BaseEyeHeight * vect(0,0,1); ViewDist = LookDir * walldist; HitActor = Trace(HitLocation, HitNormal, ViewSpot + ViewDist, ViewSpot, false); if ( HitActor == None ) return false; ViewDist = Normal(HitNormal Cross vect(0,0,1)) * walldist; if (FRand() < 0.5) ViewDist *= -1; if ( FastTrace(ViewSpot + ViewDist, ViewSpot) ) { Focus = Location + ViewDist; return true; } ViewDist *= -1; if ( FastTrace(ViewSpot + ViewDist, ViewSpot) ) { Focus = Location + ViewDist; return true; } Focus = Location - LookDir * 300; return true; } */ // Largely untested function RemoteJump() { SetPhysics(PHYS_Falling); if ( bCountJumps ) Inventory.OwnerJumped(); Velocity.Z = JumpZ; bJumpOffPawn = true; SetFall(); } //Intercept FireWeapon - is called from other code function FireWeapon(); function RemoteFireWeapon(bool bUseAltMode) { if( Weapon!=None ) { if ( (Weapon.AmmoType != None) && (Weapon.AmmoType.AmmoAmount <= 0) ) { bReadyToAttack = true; return; } ViewRotation = Rotation; PlayFiring(); if ( bUseAltMode ) { bFire = 0; bAltFire = 1; Weapon.AltFire(1.0); } else { bFire = 1; bAltFire = 0; Weapon.Fire(1.0); } } } // check for line of sight to target deltatime from now. //used by missle launcher and others to abort firing // may want to reimplement function bool CheckFutureSight(float deltatime) { return true; } /* Adjust the aim at target. - add aim error - adjust up or down if barrier Must set RemoteTarget elsewhere */ function rotator AdjustToss(float projSpeed, vector projStart, int aimerror, bool leadTarget, bool warnTarget) { local rotator FireRotation; local vector FireSpot; local actor HitActor; local vector HitLocation, HitNormal, FireDir; local float TargetDist, TossSpeed, TossTime; local int realYaw; local pawn RemoteTarget; RemoteTarget = pawn(RemoteEnemy); if ( projSpeed == 0 ) return AdjustAim(projSpeed, projStart, aimerror, leadTarget, warnTarget); if ( RemoteTarget == None || !FastTrace(RemoteTarget.Location) || !inFront(RemoteTarget.Location) ) return Rotation; FireSpot = RemoteTarget.Location; TargetDist = VSize(RemoteTarget.Location - ProjStart); if ( !RemoteTarget.bIsPawn ) { if ( (Region.Zone.ZoneGravity.Z != Region.Zone.Default.ZoneGravity.Z) || (TargetDist > projSpeed) ) { TossTime = TargetDist/projSpeed; FireSpot.Z -= ((0.25 * Region.Zone.ZoneGravity.Z * TossTime + 200) * TossTime + 60); } viewRotation = Rotator(FireSpot - ProjStart); return viewRotation; } aimerror = aimerror * (11 - 10 * ((RemoteTarget.Location - Location)/TargetDist Dot Normal((RemoteTarget.Location + 1.2 * RemoteTarget.Velocity) - (ProjStart + Velocity)))); if ( bNovice ) { if ( (RemoteTarget.Weapon == None) || !RemoteTarget.Weapon.bMeleeWeapon || (TargetDist > 650) ) aimerror = aimerror * (2.1 - 0.2 * (skill + FRand())); else aimerror *= 0.75; if ( Level.TimeSeconds - LastPainTime < 0.15 ) aimerror *= 1.3; } else { aimerror = aimerror * (1.5 - 0.35 * (skill + FRand())); if ( (Skill < 2) && (Level.TimeSeconds - LastPainTime < 0.15) ) aimerror *= 1.2; } if ( (bNovice && (LastAcquireTime > Level.TimeSeconds - 5 + 0.6 * Skill)) || (LastAcquireTime > Level.TimeSeconds - 2.5 + Skill) ) { LastAcquireTime = Level.TimeSeconds - 5; aimerror *= 1.75; } if ( !leadTarget || (accuracy < 0) ) aimerror -= aimerror * accuracy; if ( leadTarget ) { FireSpot += FMin(1, 0.7 + 0.6 * FRand()) * (Target.Velocity * TargetDist/projSpeed); if ( !FastTrace(FireSpot, ProjStart) ) FireSpot = 0.5 * (FireSpot + RemoteTarget.Location); } //try middle FireSpot.Z = RemoteTarget.Location.Z; if ( !FastTrace(FireSpot, ProjStart) ) { FireSpot = LastSeenPos; HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false); if ( HitActor != None ) { bFire = 0; bAltFire = 0; FireSpot += 2 * RemoteTarget.CollisionHeight * HitNormal; SetTimer(TimeBetweenAttacks, false); } } // adjust for toss distance (assume 200 z velocity add & 60 init height) if ( FRand() < 0.75 ) { TossSpeed = projSpeed + 0.4 * VSize(Velocity); if ( (Region.Zone.ZoneGravity.Z != Region.Zone.Default.ZoneGravity.Z) || (TargetDist > TossSpeed) ) { TossTime = TargetDist/TossSpeed; FireSpot.Z -= ((0.25 * Region.Zone.ZoneGravity.Z * TossTime + 200) * TossTime + 60); } } FireRotation = Rotator(FireSpot - ProjStart); realYaw = FireRotation.Yaw; aimerror = Rand(2 * aimerror) - aimerror; FireRotation.Yaw = (FireRotation.Yaw + aimerror) & 65535; if ( (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) > 8192) && (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) < 57343) ) { if ( (FireRotation.Yaw > Rotation.Yaw + 32768) || ((FireRotation.Yaw < Rotation.Yaw) && (FireRotation.Yaw > Rotation.Yaw - 32768)) ) FireRotation.Yaw = Rotation.Yaw - 8192; else FireRotation.Yaw = Rotation.Yaw + 8192; } FireDir = vector(FireRotation); // avoid shooting into wall HitActor = Trace(HitLocation, HitNormal, ProjStart + FMin(VSize(FireSpot-ProjStart), 400) * FireDir, ProjStart, false); if ( (HitActor != None) && (HitNormal.Z < 0.7) ) { FireRotation.Yaw = (realYaw - aimerror) & 65535; if ( (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) > 8192) && (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) < 57343) ) { if ( (FireRotation.Yaw > Rotation.Yaw + 32768) || ((FireRotation.Yaw < Rotation.Yaw) && (FireRotation.Yaw > Rotation.Yaw - 32768)) ) FireRotation.Yaw = Rotation.Yaw - 8192; else FireRotation.Yaw = Rotation.Yaw + 8192; } FireDir = vector(FireRotation); } if ( warnTarget && (RemoteTarget != None) ) RemoteTarget.WarnTarget(self, projSpeed, FireDir); viewRotation = FireRotation; return FireRotation; } function rotator AdjustAim(float projSpeed, vector projStart, int aimerror, bool leadTarget, bool warnTarget) { local rotator FireRotation, TargetLook; local vector FireSpot, FireDir, TargetVel; local float FireDist, TargetDist; local actor HitActor; local vector HitLocation, HitNormal; local int realYaw; local bool bDefendMelee, bClean; local pawn RemoteTarget; RemoteTarget = pawn(RemoteEnemy); if ( RemoteTarget == None ) { bFire = 0; bAltFire = 0; return Rotation; } if ( !FastTrace(RemoteTarget.Location) || !inFront(RemoteTarget.Location) ) { return Rotation; } if ( !RemoteTarget.bIsPawn || RemoteTarget.IsA('FortStandard') ) return rotator(RemoteTarget.Location - projstart); FireSpot = RemoteTarget.Location; TargetDist = VSize(RemoteTarget.Location - Location); aimerror = aimerror * (11 - 10 * ((RemoteTarget.Location - Location)/TargetDist Dot Normal((RemoteTarget.Location + 1.25 * RemoteTarget.Velocity) - (Location + Velocity)))); bDefendMelee = ( (RemoteTarget.Weapon != None) && RemoteTarget.Weapon.bMeleeWeapon && (TargetDist < 700) ); if ( bDefendMelee ) aimerror *= 0.5; if ( ((projSpeed == 0) || (Projspeed >= 1000000)) ) { // instant hit if ( bNovice ) aimerror *= 0.5; else aimerror *= 0.5 + 0.19 * skill; } if ( bNovice ) { if ( !bDefendMelee ) aimerror = aimerror * (2.4 - 0.2 * (skill + FRand())); if ( (Level.TimeSeconds - LastPainTime < 0.2) || (Physics == PHYS_Falling) || (RemoteTarget.Physics == PHYS_Falling) ) aimerror *= 1.5; } else { aimerror = aimerror * (1.7 - 0.4 * (skill + FRand())); if ( (Skill < 2) && ((Level.TimeSeconds - LastPainTime < 0.15) || (Physics == PHYS_Falling) || (RemoteTarget.Physics == PHYS_Falling)) ) aimerror *= 1.2; } if ( (bNovice && (LastAcquireTime > Level.TimeSeconds - 5 + 0.5 * skill)) || (LastAcquireTime > Level.TimeSeconds - 2.5 + skill) ) { LastAcquireTime = Level.TimeSeconds - 5; if ( bDefendMelee ) aimerror *= 1.3; else aimerror *= 2; } if ( !leadTarget || (accuracy < 0) ) aimerror -= aimerror * accuracy; if (leadTarget && (projSpeed > 0)) { TargetVel = RemoteTarget.Velocity; if ( RemoteTarget.Physics == PHYS_Falling ) { if ( RemoteTarget.Region.Zone.ZoneGravity == RemoteTarget.Region.Zone.Default.ZoneGravity ) TargetVel.Z = FMin(-160, TargetVel.Z); else TargetVel.Z = FMin(0, TargetVel.Z); } FireSpot += FMin(1, 0.7 + 0.6 * FRand()) * TargetVel * TargetDist/projSpeed; FireSpot.Z = FMin(RemoteTarget.Location.Z, FireSpot.Z); if ( (RemoteTarget.Physics != PHYS_Falling) && (FRand() < 0.55) && (VSize(FireSpot - ProjStart) > 1000) ) { TargetLook = RemoteTarget.Rotation; if ( RemoteTarget.Physics == PHYS_Walking ) TargetLook.Pitch = 0; if ( ((Vector(TargetLook) Dot Normal(RemoteTarget.Velocity)) < 0.71) ) bClean = false; else bClean = FastTrace(FireSpot, ProjStart); } else bClean = FastTrace(FireSpot, ProjStart); if ( !bClean) { if ( FRand() < 0.3 ) FireSpot = RemoteTarget.Location; else FireSpot = 0.5 * (FireSpot + RemoteTarget.Location); } } bClean = false; //so will fail first check unless shooting at feet if ( RemoteTarget.bIsPawn && (!bNovice || bDefendMelee) && (Weapon != None) && (Weapon.bRecommendSplashDamage || (Weapon.bRecommendAltSplashDamage && (bAltFire != 0))) && (((RemoteTarget.Physics == PHYS_Falling) && (Location.Z + 80 >= RemoteTarget.Location.Z)) || ((Location.Z + 19 >= RemoteTarget.Location.Z) && (bDefendMelee || (skill > 2.5 * FRand() - 0.5)))) ) { HitActor = Trace(HitLocation, HitNormal, FireSpot - vect(0,0,1) * (RemoteTarget.CollisionHeight + 6), FireSpot, false); bClean = (HitActor == None); if ( !bClean ) { FireSpot = HitLocation + vect(0,0,3); bClean = FastTrace(FireSpot, ProjStart); } else if ( RemoteTarget.Physics == PHYS_Falling ) bClean = FastTrace(FireSpot, ProjStart); else bClean = false; } if ( !bClean ) { //try middle FireSpot.Z = RemoteTarget.Location.Z; bClean = FastTrace(FireSpot, ProjStart); } if( !bClean ) { ////try head FireSpot.Z = RemoteTarget.Location.Z + 0.9 * RemoteTarget.CollisionHeight; bClean = FastTrace(FireSpot, ProjStart); } FireRotation = Rotator(FireSpot - ProjStart); realYaw = FireRotation.Yaw; aimerror = Rand(2 * aimerror) - aimerror; FireRotation.Yaw = (FireRotation.Yaw + aimerror) & 65535; if ( (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) > 8192) && (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) < 57343) ) { if ( (FireRotation.Yaw > Rotation.Yaw + 32768) || ((FireRotation.Yaw < Rotation.Yaw) && (FireRotation.Yaw > Rotation.Yaw - 32768)) ) FireRotation.Yaw = Rotation.Yaw - 8192; else FireRotation.Yaw = Rotation.Yaw + 8192; } FireDir = vector(FireRotation); // avoid shooting into wall FireDist = FMin(VSize(FireSpot-ProjStart), 400); FireSpot = ProjStart + FireDist * FireDir; HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false); if ( HitActor != None ) { if ( HitNormal.Z < 0.7 ) { FireRotation.Yaw = (realYaw - aimerror) & 65535; if ( (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) > 8192) && (Abs(FireRotation.Yaw - (Rotation.Yaw & 65535)) < 57343) ) { if ( (FireRotation.Yaw > Rotation.Yaw + 32768) || ((FireRotation.Yaw < Rotation.Yaw) && (FireRotation.Yaw > Rotation.Yaw - 32768)) ) FireRotation.Yaw = Rotation.Yaw - 8192; else FireRotation.Yaw = Rotation.Yaw + 8192; } FireDir = vector(FireRotation); FireSpot = ProjStart + FireDist * FireDir; HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false); } if ( HitActor != None ) { FireSpot += HitNormal * 2 * RemoteTarget.CollisionHeight; if ( !bNovice ) { HitActor = Trace(HitLocation, HitNormal, FireSpot, ProjStart, false); if ( HitActor != None ) FireSpot += RemoteTarget.CollisionHeight * HitNormal; } FireDir = Normal(FireSpot - ProjStart); FireRotation = rotator(FireDir); } } if ( warnTarget && (RemoteTarget != None) ) RemoteTarget.WarnTarget(self, projSpeed, FireDir); viewRotation = FireRotation; return FireRotation; } // Let Bot know about incoming projectiles function WarnTarget(Pawn shooter, float projSpeed, vector FireDir) { local float enemyDist; local vector X,Y,Z, enemyDir; // AI controlled creatures may duck if not falling if ( (health <= 0) || !bCanDuck || (Enemy == None) || (Physics == PHYS_Falling) || (Physics == PHYS_Swimming) ) return; if ( bNovice ) { if ( FRand() > 0.11 * skill ) return; } else if ( FRand() > 0.22 * skill + 0.33 ) return; // and projectile time is long enough enemyDist = VSize(shooter.Location - Location); if (enemyDist/projSpeed < 0.11 + 0.15 * FRand()) return; // only if tight FOV GetAxes(Rotation,X,Y,Z); enemyDir = (shooter.Location - Location)/enemyDist; if ((enemyDir Dot X) < 0.8) return; myConnection.SendLine("PRJ" $ib$as$ "Time" $ib$ (enemyDist/projSpeed) $ae$ib$as$ "Direction" $ib$ rotator(enemyDir) $ae); } function TryToDuck(vector duckDir, bool bReversed); // CloseToPointMan - called if orders are 'follow' to check if close enough to point man function bool CloseToPointMan(Pawn Other) { //return what engine wants to hear return true; } //Don't need our bots autotaunting function MaybeTaunt(Pawn Other); //Called when someone other than this bot dies. function Killed(pawn Killer, pawn Other, name damageType) { local Pawn aPawn; if ( Killer == self ) Other.Health = FMin(Other.Health, -11); // don't let other do stagger death if ( Health <= 0 ) return; if ( OldEnemy == Other ) OldEnemy = None; if ( Enemy == Other ) { Enemy = None; } myConnection.SendLine("KIL" $ib$as$ "Id" $ib$ Other $ae$ib$as$ "Killer" $ib$ Killer $ae$ib$as$ "DamageType" $ib$ damageType $ae); } //Pointless callback function EnemyAcquired(); //All kinds of shit can call this mostly special trigger points function Trigger( actor Other, pawn EventInstigator ) { //SENDMESSAGE } //Much of translocator brains implemented in translocator //For now better off playing without it - need to research how //it interacts with path finding function TranslocateToTarget(Actor Destn) { MyTranslocator.DesiredTarget = Destn; } //Don't let engine pick nodes that must be impact jumped function bool CanImpactJump() { return false; } //Don't handle impact jumps or low gravity manuevers for bots function ImpactJump(Actor JumpDest); function BigJump(Actor JumpDest); //Don't have engine direct to Ambush function bool FindAmbushSpot() { return false; } //Called when bot dies function Died(pawn Killer, name damageType, vector HitLocation) { Super.Died(Killer, damageType, HitLocation); myConnection.SendLine("DIE" $ib$as$ "Killer" $ib$ Killer $ae$ib$as$ "DamageType" $ib$ damageType $ae); } //Called when bot is injured function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { local float enemyDist; local vector enemyDir, X, Y, Z; local string messageString; Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); messageString = "DAM" $ib$as$ "Damage" $ib$ Damage $ae$ib$as$ "DamageType" $ib$ damageType $ae; // !!! need to fix this and projectile detection to match our //periphreal vision parameter. // only if tight FOV GetAxes(Rotation,X,Y,Z); enemyDist = VSize(instigatedBy.Location - Location); enemyDir = (instigatedBy.Location - Location)/enemyDist; if ((enemyDir Dot X) > 0.8) messageString = messageString $ib$as$ "Instigator" $ib$ instigatedBy $ae; myConnection.SendLine(messageString); } //********************************************************************************** //Base Monster AI /* auto state StartUp { function BeginState() { SetMovementPhysics(); if (Physics == PHYS_Walking) SetPhysics(PHYS_Falling); } Begin: } */ auto state StartUp { function BeginState() { SetMovementPhysics(); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { Global.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } function Landed(vector HitNormal) { Global.Landed(HitNormal); } function Timer(); Begin: if (Physics != PHYS_Falling) { Velocity = vect(0,0,0); Acceleration = vect(0,0,0); MoveTimer = -1.0; } PlayWaiting(); sleep( 30 ); goto 'Begin'; Test: bFire = 0; RemoteEnemy=none; Enemy=none; PlayDuck(); sleep( 30 ); goto 'Test'; Move: if(bIsWalking) PlayWalking(); else PlayRunning(); MoveTo(myDestination, GetSpeed() ); if( VSize(Location - myDestination) > CollisionRadius ) { goto 'Move'; } goto 'Begin'; Strafe: PlayRunning(); if(RemoteFocus == none) StrafeTo(myDestination, myFocus); else StrafeFacing(myDestination, RemoteFocus); if( VSize(Location - myDestination) > CollisionRadius ) goto 'Strafe'; goto 'Begin'; Tracking: if (Physics != PHYS_Falling) { Velocity = vect(0,0,0); Acceleration = vect(0,0,0); MoveTimer = -1.0; } if ( RemoteFocus == none || !FastTrace(RemoteFocus.Location) ) { goto 'Begin'; } else { PlayTurning(); TurnToward(RemoteFocus); Sleep(0.05); goto 'Tracking'; } Turning: if (Physics != PHYS_Falling) { Velocity = vect(0,0,0); Acceleration = vect(0,0,0); MoveTimer = -1.0; } if(RemoteFocus != none) TurnToward(RemoteFocus); else TurnTo(myFocus); goto 'Begin'; } state TakeHit { //ignores seeplayer, hearnoise, bump, hitwall; function Timer(); Begin: error("!!!TakeHit"); GotoState(NextState,NextLabel); } state FallingState { ignores Bump, Hitwall, WarnTarget; singular event BaseChange() { Global.BaseChange(); } function AnimEnd() { PlayInAir(); } function ZoneChange(ZoneInfo newZone) { Global.ZoneChange(newZone); if (newZone.bWaterZone) { TweenToWaiting(0.15); GotoState('FallingState', 'Splash'); } } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { Global.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } function bool SetEnemy(Pawn NewEnemy) { Global.SetEnemy(NewEnemy); } function Timer(); function Landed(vector HitNormal) { local vector Vel2D; if ( MoveTarget != None ) { Vel2D = Velocity; Vel2D.Z = 0; if ( (Vel2D Dot (MoveTarget.Location - Location)) < 0 ) Acceleration = vect(0,0,0); } //Note - physics changes type to PHYS_Walking by default for landed pawns PlayLanded(Velocity.Z); TakeFallingDamage(); if (Velocity.Z < -1.4 * JumpZ) { if ( health > 0 ) GotoState('FallingState', 'Landed'); } else GotoState('FallingState', 'Done'); } function SeePlayer(Actor SeenPlayer) { Global.SeePlayer(SeenPlayer); } function EnemyNotVisible() { Global.EnemyNotVisible(); } function SetFall() { if (!bUpAndOut) GotoState('FallingState'); } function EnemyAcquired() { Global.EnemyAcquired(); } function BeginState(); function EndState() { //log(self$" left falling state "); bUpAndOut = false; bJumpOffPawn = false; bBigJump = false; if ( bImpactJumping ) { bImpactJumping = false; SwitchToBestWeapon(); } } FireWhileFalling: if ( Physics != PHYS_Falling ) Goto('Done'); else Sleep(0.5 + 0.2 * FRand()); if ( LineOfSightTo(Enemy) ) Goto('FireWhileFalling'); LongFall: if ( bCanFly ) { SetPhysics(PHYS_Flying); Goto('Done'); } Sleep(0.7); if ( (Velocity.Z > -150) && (Region.Zone.ZoneGravity.Z <= Region.Zone.Default.ZoneGravity.Z) ) //stuck { SetPhysics(PHYS_Falling); Velocity = groundspeed * VRand(); Velocity.Z = FMax(JumpZ, 250); } Goto('LongFall'); Landed: //log("Playing"@animsequence@"at"@animframe); Disable('AnimEnd'); FinishAnim(); //log("Finished"@animsequence@"at"@animframe); Done: //log("After fall"@NextState@NextLabel); if ( NextAnim == '' ) { bUpAndOut = false; if ( (NextState != '') && (NextState != 'FallingState') ) GotoState(NextState, NextLabel); else { log("Going from -Done"); GotoState('StartUp'); } } if ( !bUpAndOut ) { if ( NextAnim == 'Fighter' ) TweenToFighter(0.2); else TweenAnim(NextAnim, 0.12); } Splash: bUpAndOut = false; if ( NextState != '' ) GotoState(NextState, NextLabel); else { log("Going from -Splash"); GotoState('StartUp'); } Begin: if ( !bUpAndOut ) // not water jump { if ( Region.Zone.bWaterZone ) { SetPhysics(PHYS_Swimming); GotoState(NextState, NextLabel); } PlayFall: if ( (Velocity.Z > 300) && (MoveTarget != None) && ((FRand() < 0.13) || ((Region.Zone.ZoneGravity.Z > Region.Zone.Default.ZoneGravity.Z) && (FRand() < 0.2))) && (VSize(Destination - Location) > 160) && ((Vector(Rotation) Dot (Destination - Location)) > 0) ) PlayFlip(); else TweenToFalling(); } if (Physics != PHYS_Falling) Goto('Done'); if ( bJumpOffPawn ) { if ( bBigJump ) { While( bBigJump ) { Sleep(0.25); Acceleration = AccelRate * Normal(Destination - Location); } } else { Sleep(0.2); While ( (Abs(Velocity.X) < 60) && (Abs(Velocity.Y) < 60) ) Sleep(0.1); Acceleration = vect(0,0,0); Sleep(1.5); } bBigJump = false; bJumpOffPawn = false; } else Sleep(2); Goto('LongFall'); Ducking: if ( Region.Zone.ZoneGravity.Z > Region.Zone.Default.ZoneGravity.Z ) { Acceleration = AccelRate * Normal(Destination - Location); if ( bNovice ) Sleep(0.4); PlayInAir(); } } //called from pressure zone just get the hell back out state VictoryDance { function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { Global.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } function EnemyAcquired() { Global.EnemyAcquired(); } function BeginState(); Begin: GotoState(NextState,NextLabel); } state GameEnded { ignores SeePlayer, EnemyNotVisible, HearNoise, TakeDamage, Died, Bump, Trigger, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, PainTimer; function SpecialFire() { } function TryToDuck(vector duckDir, bool bReversed) { } function SetFall() { } function LongFall() { } function Killed(pawn Killer, pawn Other, name damageType) { } function ClientDying(name DamageType, vector HitLocation) { } function BeginState() { AnimRate = 0.0; bFire = 0; bAltFire = 0; SimAnim.Y = 0; SetCollision(false,false,false); SetPhysics(PHYS_None); Velocity = vect(0,0,0); myConnection.SendLine("FIN"); } } state Dying { ignores SeePlayer, EnemyNotVisible, HearNoise, Died, Bump, Trigger, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, LongFall, SetFall, PainTimer; function ReStartPlayer() { if( bHidden && Level.Game.RestartPlayer(self) ) { if ( bNovice ) bDumbDown = ( FRand() < 0.5 ); else bDumbDown = ( FRand() < 0.35 ); Velocity = vect(0,0,0); Acceleration = vect(0,0,0); ViewRotation = Rotation; ReSetSkill(); SetPhysics(PHYS_Falling); SetOrders(BotReplicationInfo(PlayerReplicationInfo).RealOrders, BotReplicationInfo(PlayerReplicationInfo).RealOrderGiver, true); GotoState('StartUp'); } else if ( !IsInState('GameEnded') ) { GotoState('Dying', 'TryAgain'); } } function BeginState() { Enemy = None; PointDied = -1000; bFire = 0; bAltFire = 0; bInitLifeMessage = false; MyTranslocator = None; } Begin: if ( Level.Game.bGameEnded ) GotoState('GameEnded'); Sleep(0.2); if ( !bHidden ) SpawnCarcass(); TryAgain: if ( !bHidden ) { HidePlayer(); } Sleep(0.25 + DeathMatchPlus(Level.Game).SpawnWait(self)); ReStartPlayer(); Goto('TryAgain'); WaitingForStart: bHidden = true; } //-------------RemoteBot Specific Functions-------------------- //Check to see if a location is really in front of the bot //may be a more efficient algorithm function bool inFront(Vector A) { local rotator angle; //can't be infront if inside bot if( VSize(Location - A) < CollisionRadius ) return false; angle = ( Rotation - rotator(A - Location) ); if( (cos(angle.Yaw / 10435.0) < remoteVisionLimit) || (cos(angle.Pitch / 10435.0) < remoteVisionLimit) ) return false; else return true; } //Called by the gametype when someone else is injured by the bot function int HurtOther(int Damage, name DamageType, pawn injured) { myConnection.SendLine("HIT" $ib$as$ "Id" $ib$ injured $ae$ib$as$ "Damage" $ib$ Damage $ae$ib$as$ "DamageType" $ib$ DamageType $ae); } function checkSelf() { local int ArmorAmount,i; local inventory Inv; local string outstring; ArmorAmount = 0; i = 0; for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) { if (Inv.bIsAnArmor) { ArmorAmount += Inv.Charge; } else { i++; if ( i > 100 ) break; // can occasionally get temporary loops in netplay } } outstring = "SLF" $ib$as$ "Id" $ib$ self $ae$ib$as$ "Rotation" $ib$ Rotation $ae$ib$as$ "Location" $ib$ Location $ae$ib$as$ "Velocity" $ib$ Velocity $ae$ib$as$ "Name" $ib$ PlayerReplicationInfo.PlayerName $ae$ib$as$ "Team" $ib$ PlayerReplicationInfo.Team $ae$ib$as$ "Health" $ib$ Health $ae$ib$as$ "Weapon" $ib$ Weapon $ae$ib$as$ "CurrentAmmo" $ib$ Weapon.AmmoType.AmmoAmount $ae$ib$as$ "Armor" $ib$ ArmorAmount $ae; if( bFire != 0 ) outstring = outstring $ib$as$ "Firing" $ib$ "1" $ae; else if( bAltFire != 0 ) outstring = outstring $ib$as$ "AltFiring" $ib$ "2" $ae; else outstring = outstring $ib$as$ "AltFiring" $ib$ "0" $ae; myConnection.sendLine(outstring); } function checkVision() { local Inventory I; local Mover M; local Pawn P; local CTFFlag C; local NavigationPoint N; local vector HitL, HitN; local int temp; local string outstring; //!!! view rotation sometimes falls out of synch with rotation? wtf?? for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if( (P != self) && !P.bHidden && FastTrace(P.Location) && inFront(P.Location) && ( Trace(HitL, HitN, P.Location) == P) ) { outstring = "PLR" $ib$as$ "Id" $ib$ P $ae$ib$as$ "Rotation" $ib$ P.Rotation $ae$ib$as$ "Location" $ib$ P.Location $ae$ib$as$ "Velocity" $ib$ P.Velocity $ae$ib$as$ "Name" $ib$ PlayerReplicationInfo.PlayerName $ae$ib$as$ "Team" $ib$ P.PlayerReplicationInfo.Team $ae$ib$as$ "Reachable" $ib$ actorReachable(P) $ae$ib$as$ "Weapon" $ib$ P.Weapon.Class $ae; if( P.bFire != 0 ) outstring = outstring $ib$as$ "Firing" $ib$ "1" $ae; else if( P.bAltFire != 0 ) outstring = outstring $ib$as$ "AltFiring" $ib$ "2" $ae; else outstring = outstring $ib$as$ "AltFiring" $ib$ "0" $ae; myConnection.sendLine(outstring); } } foreach VisibleCollidingActors(class'Inventory',I,SightRadius) { if( I.GetStateName() == 'Pickup'&& !I.bHidden && inFront(I.Location) && ( Trace(HitL, HitN, I.Location) == none) ) { myConnection.SendLine("INV" $ib$as$ "Id" $ib$ I $ae$ib$as$ "Location" $ib$ I.Location $ae$ib$as$ "Reachable" $ib$ actorReachable(I) $ae$ib$as$ "Class" $ib$ I.Class $ae); } } foreach VisibleCollidingActors(class'Mover',M,SightRadius) { if( !M.bHidden && inFront(M.Location) && ( Trace(HitL, HitN, M.Location) == none) ) { myConnection.SendLine("MOV" $ib$as$ "Id" $ib$ M $ae$ib$as$ "Location" $ib$ M.Location $ae$ib$as$ "Reachable" $ib$ actorReachable(M) $ae$ib$as$ "DamageTrig" $ib$ M.bDamageTriggered $ae$ib$as$ "Class" $ib$ M.Class $ae); } } for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) { //try letting them see inv navpoints - may be needed for some levels //if( !N.IsA('InventorySpot') && FastTrace(N.Location) && inFront(N.Location)) if( FastTrace(N.Location) && inFront(N.Location) && ( Trace(HitL, HitN, N.Location) == none) ) { if(N.IsA('ControlPoint')) { if( ControlPoint(N).ControllingTeam == none ) temp = 255; else temp = ControlPoint(N).ControllingTeam.TeamIndex; myConnection.SendLine("DOM" $ib$as$ "Id" $ib$ N $ae$ib$as$ "Location" $ib$ N.Location $ae$ib$as$ "Reachable" $ib$ actorReachable(N) $ae$ib$as$ "Controller" $ib$ temp $ae); } else myConnection.SendLine("NAV" $ib$as$ "Id" $ib$ N $ae$ib$as$ "Location" $ib$ N.Location $ae$ib$as$ "Reachable" $ib$ actorReachable(N) $ae); } } if (myConnection.Parent.gameClass == "BotCTF") { foreach AllActors (class'CTFFlag', C) { //not using trace because players tend to obstruct flags wildly if( FastTrace(C.Location) && inFront(C.Location) && C.Holder != self ) { outstring = "FLG" $ib$as$ "Id" $ib$ C $ae; //when a flag is held its location is not updated by engine =( if( C.GetStateName() == 'Held') outstring = outstring $ib$as$ "Location" $ib$ C.Holder.Location $ae$ib$as$ "Holder" $ib$ C.Holder $ae; else outstring = outstring $ib$as$ "Location" $ib$ C.Location $ae; outstring = outstring $ib$as$ "Team" $ib$ C.Team $ae$ib$as$ "Reachable" $ib$ actorReachable(C) $ae$ib$as$ "State" $ib$ C.GetStateName() $ae; myConnection.SendLine(outstring); } } } } //Shortten up the MakeItem calls function string MakeItem(string first, string second) { return myConnection.MakeItem(first,second); } //----------------- ps[>s[~[H ::$x-oVizServer: Listening again - connections have been closed.r H ca=sc^% ^ ::$-yBotServer: Too many connections - closing down Listen.W ^//============================================================================= // Mutator. //============================================================================= class PathMarkerMutator expands Mutator; var bool bInited; event PostBeginPlay() { local NavigationPoint N; if(!bInited) { bInited = true; for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) { if(!N.IsA('InventorySpot')) spawn(class'BotAPI.PathMarker',N,,N.Location); } } } W 0Iz rFCAnAD @rD?,?A,JD?,?rND?,,|D?N, Oo ^rw*A.~ ?r?A?A OB A ^zAo%A$w*B.~ ?J?A?B OyB ^pBo%B$?, wUZ}f=$:ew4w4w4w4 2V//============================================================================= // PathMarker. //============================================================================= class PathMarker extends Actor; ~//============================================================================= // BotTeamGamePlus. //============================================================================= class BotTeamGamePlus extends TeamGamePlus config(BotAPI); var VizServer theVizServer; var BotServer theBotServer; var bool bServerLoaded; var RemoteBotInfo RemoteBotConfig; var int NumRemoteBots; function PostBeginPlay() { Super.PostBeginPlay(); if(!bServerLoaded) { theVizServer = spawn(class'VizServer',self); theVizServer.gameClass = "BotTeamGamePlus"; theBotServer = spawn(class'BotServer',self); theBotServer.gameClass = "BotTeamGamePlus"; bServerLoaded = true; } RemoteBotConfig = spawn(class'RemoteBotInfo',self); RemoteBotConfig.Difficulty = BotConfig.Difficulty; } function string GetGameInfo() { local string ib, as, ae; local string outStr; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = (ib$as$ "GoalTeamScore" $ib$ GoalTeamScore $ae$ib$as$ "TimeLimit" $ib$ TimeLimit $ae$ib$as$ "MaxTeams" $ib$ MaxTeams $ae$ib$as$ "MaxTeamSize" $ib$ MaxTeamSize $ae); return outStr; } function string GetGameStatus() { local string ib, as, ae; local string outStr; local int i; local Pawn P; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = "GAM"; outStr = ( outStr $ib$as$ "PlayerScores" ); for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if( !P.IsA('Spectator') ) outStr = ( outStr $ib$as$ P $ib$ P.PlayerReplicationInfo.Score $ae ); } outStr = ( outStr $ae ); outStr = ( outStr $ib$as$ "TeamScores" ); for (i=0;i bigsize ) { big = i; bigsize = Teams[i].Size; } else if ( Teams[i].Size < smallsize ) { small = i; smallsize = Teams[i].Size; } } bBalancing = true; while ( bigsize - smallsize > 1 ) { for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo.Team == big) && P.IsA('Bot') && !P.IsA('RemoteBot') ) { B = Bot(P); break; } if ( B != None ) { B.Health = 0; B.Died( None, 'Suicided', B.Location ); bigsize--; smallsize++; ChangeTeam(B, small); } else Break; } bBalancing = false; // re-assign orders to follower bots with no leaders for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && P.IsA('Bot') && !P.IsA('RemoteBot') && (BotReplicationInfo(P.PlayerReplicationInfo).RealOrders == 'Follow') ) { A = Pawn(Bot(P).OrderObject); if ( (A == None) || A.bDeleteMe || !A.bIsPlayer || (A.PlayerReplicationInfo.Team != P.PlayerReplicationInfo.Team) ) { Bot(P).OrderObject = None; SetBotOrders(Bot(P)); } } } //Hook in here to send damage messages may not be 100% reliable because //Mutator's MutatorTakeDamage call happens in pawn, after this. So a mutator //that changes damage will not be considered for HurtOther message function int ReduceDamage(int Damage, name DamageType, pawn injured, pawn instigatedBy) { local RemoteBot theBot; theBot = RemoteBot(instigatedBy); Damage = Super.ReduceDamage(Damage, DamageType, injured, instigatedBy); if( theBot != none) theBot.HurtOther((Damage * instigatedBy.DamageScaling), DamageType, Injured); return Damage; } function bool ChangeTeam(Pawn Other, int NewTeam) { local int i, s, DesiredTeam; local pawn APlayer, P; local teaminfo SmallestTeam; if ( bRatedGame && (Other.PlayerReplicationInfo.Team != 255) ) return false; if ( Other.PlayerReplicationInfo.Team != 255 ) { ClearOrders(Other); Teams[Other.PlayerReplicationInfo.Team].Size--; } for( i=0; i Teams[i].Size) ) { s = i; SmallestTeam = Teams[i]; } } if ( bPlayersBalanceTeams ) { if ( NumBots == 1 ) { // join bot's team, because he will leave for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('Bot') && !P.IsA('RemoteBot') ) break; if ( (P != None) && (P.PlayerReplicationInfo != None) && (Teams[P.PlayerReplicationInfo.Team].Size == SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = P.PlayerReplicationInfo.Team; } else if ( (NewTeam >= MaxTeams) || (Teams[NewTeam].Size > SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = 255; } } else if ( (NewTeam >= MaxTeams) || (Teams[NewTeam].Size > SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = 255; } } if ( (NewTeam == 255) || (NewTeam >= MaxTeams) ) NewTeam = s; if ( Other.IsA('Spectator') ) { Other.PlayerReplicationInfo.Team = 255; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); return true; } if ( Other.IsA('Commander') ) { Other.PlayerReplicationInfo.Team = NewTeam; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); return true; } if ( (Other.PlayerReplicationInfo.Team == NewTeam) && bNoTeamChanges ) return false; if ( Other.IsA('TournamentPlayer') ) TournamentPlayer(Other).StartSpot = None; if (Teams[NewTeam].Size < MaxTeamSize) { AddToTeam(NewTeam, Other); return true; } if ( (SmallestTeam != None) && (SmallestTeam.Size < MaxTeamSize) ) { AddToTeam(s, Other); return true; } return false; } //Shouldn't matter - dont think it is actually called in teamgames //voided for remoteBots anyway though function SetAttractionStateFor(Bot aBot) { if ( !aBot.IsA('RemoteBot') ) { if ( aBot.Enemy != None ) { if ( !aBot.IsInState('FallBack') ) { aBot.bNoClearSpecial = true; aBot.TweenToRunning(0.1); aBot.GotoState('FallBack','SpecialNavig'); } } else if ( !aBot.IsInState('Roaming') ) { aBot.bNoClearSpecial = true; aBot.TweenToRunning(0.1); aBot.GotoState('Roaming', 'SpecialNavig'); } } } function ClearOrders(Pawn Leaving) { local Pawn P; for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('Bot') && !P.IsA('RemoteBot') && (Bot(P).OrderObject == Leaving) ) Bot(P).SetOrders('Freelance', None); } //Controls gamestart - must have at least one player/remote bot in game, //then waits for CountDown length (note that in standalone (i.e. practice //session games) CountDown is set to 1 automatically. function Timer() { local Pawn P; local bool bReady; local int M; Super(GameInfo).Timer(); if ( bNetReady ) { if ( NumPlayers + NumRemoteBots > 0 ) ElapsedTime++; else ElapsedTime = 0; if ( ElapsedTime > NetWait ) { if ( (NumPlayers + NumBots + NumRemoteBots < 4) && NeedPlayers() ) AddBot(); else if ( (NumPlayers + NumBots + NumRemoteBots > 1) || ((NumPlayers + NumRemoteBots > 0) && (ElapsedTime > 2 * NetWait)) ) bNetReady = false; } if ( bNetReady ) { for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); return; } else { while ( NeedPlayers() ) AddBot(); bRequireReady = false; StartMatch(); } } if ( bRequireReady && (CountDown > 0) ) { while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); if ( ((NumPlayers == MaxPlayers) || (Level.NetMode == NM_Standalone)) && (RemainingBots <= 0) ) { bReady = true; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') && !P.IsA('Spectator') && !PlayerPawn(P).bReadyToPlay ) bReady = false; if ( bReady ) { StartCount = 30; CountDown--; if ( CountDown <= 0 ) StartMatch(); else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); if ( (CountDown < 11) && P.IsA('TournamentPlayer') ) TournamentPlayer(P).TimeMessage(CountDown); else PlayerPawn(P).SetProgressMessage(CountDown$CountDownMessage, 0); } } } else if ( StartCount > 8 ) { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); PlayerPawn(P).SetProgressTime(2); PlayerPawn(P).SetProgressMessage(WaitingMessage1, 0); PlayerPawn(P).SetProgressMessage(WaitingMessage2, 1); if ( PlayerPawn(P).bReadyToPlay ) PlayerPawn(P).SetProgressMessage(ReadyMessage, 2); else PlayerPawn(P).SetProgressMessage(NotReadyMessage, 2); } } else { StartCount++; if ( Level.NetMode != NM_Standalone ) StartCount = 30; } } else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) PlayStartupMessage(PlayerPawn(P)); } } else { if ( bAlwaysForceRespawn || (bForceRespawn && (Level.NetMode != NM_Standalone)) ) For ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if ( P.IsInState('Dying') && P.IsA('PlayerPawn') && P.bHidden ) PlayerPawn(P).ServerReStartPlayer(); } if ( NeedPlayers() ) AddBot(); else while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; if ( bGameEnded ) { if ( Level.TimeSeconds > EndTime + RestartWait ) RestartGame(); } else if ( !bOverTime && (TimeLimit > 0) ) { GameReplicationInfo.bStopCountDown = false; RemainingTime--; GameReplicationInfo.RemainingTime = RemainingTime; if ( RemainingTime % 60 == 0 ) GameReplicationInfo.RemainingMinute = RemainingTime; if ( RemainingTime <= 0 ) EndGame("timelimit"); } else { ElapsedTime++; GameReplicationInfo.ElapsedTime = ElapsedTime; } } } function RemoteBot AddRemoteBot(BotConnection theConnection, string clientName, int teamNum) { local RemoteBot NewBot; local NavigationPoint StartSpot, OldStartSpot; local int DesiredTeam, i, MinSize; NewBot = SpawnRemoteBot(StartSpot, theConnection); if ( NewBot == None ) { log("Failed to spawn remote bot"); return none; } NewBot.PlayerReplicationInfo.Team = teamNum; if ( clientName != "" ) NewBot.PlayerReplicationInfo.Team = teamNum; if ( bBalanceTeams && !bRatedGame ) { MinSize = Teams[0].Size; DesiredTeam = 0; for ( i=1; i= MaxTeams ) NextBotTeam = 0; } if ( bSpawnInTeamArea ) { OldStartSpot = StartSpot; StartSpot = FindPlayerStart(NewBot,255); if ( StartSpot != None ) { NewBot.SetLocation(StartSpot.Location); NewBot.SetRotation(StartSpot.Rotation); NewBot.ViewRotation = StartSpot.Rotation; NewBot.SetRotation(NewBot.Rotation); StartSpot.PlayTeleportEffect( NewBot, true ); } else StartSpot = OldStartSpot; } StartSpot.PlayTeleportEffect(NewBot, true); // Log it. if (LocalLog != None) { LocalLog.LogPlayerConnect(NewBot); LocalLog.FlushLog(); } if (WorldLog != None) { WorldLog.LogPlayerConnect(NewBot); WorldLog.FlushLog(); } NumRemoteBots++; return NewBot; } function bool ForceAddBot() { // add bot during gameplay if ( Level.NetMode != NM_Standalone ) MinPlayers = Max(MinPlayers+1, NumPlayers + NumRemoteBots + NumBots + 1); AddBot(); } function bool OneOnOne() { return ( NumPlayers + NumBots + NumRemoteBots == 2 ); } function bool NeedPlayers() { return (!bGameEnded && (NumPlayers + NumBots + NumRemoteBots < MinPlayers)); } function bool TooManyBots() { return (NumBots + NumPlayers + NumRemoteBots > MinPlayers); } function bool RestartPlayer( pawn aPlayer ) { local Bot B; local bool bResult; aPlayer.DamageScaling = aPlayer.Default.DamageScaling; B = Bot(aPlayer); if ( (B != None) && (!B.IsA('RemoteBot')) && TooManyBots() ) { log("Destroying bot"); aPlayer.Destroy(); return false; } bResult = Super(GameInfo).RestartPlayer(aPlayer); if ( aPlayer.IsA('TournamentPlayer') ) TournamentPlayer(aPlayer).StartSpot = LastStartSpot; return bResult; } function RemoteBot SpawnRemoteBot(out NavigationPoint StartSpot, BotConnection theConnection) { local RemoteBot NewBot; local int BotN; local Pawn P; BotN = RemoteBotConfig.ChooseBotInfo(); // Find a start spot. StartSpot = FindPlayerStart(None, 255); if( StartSpot == None ) { log("Could not find starting spot for RemoteBot"); return None; } // Try to spawn the bot. NewBot = Spawn(RemoteBotConfig.CHGetBotClass(BotN),,,StartSpot.Location,StartSpot.Rotation); if ( NewBot == None ) log("Couldn't spawn player at "$StartSpot); if ( NewBot != None ) { //hook up connection to socket NewBot.myConnection = theConnection; NewBot.as = theConnection.as; NewBot.ae = theConnection.ae; NewBot.ib = theConnection.ib; // Set the player's ID. NewBot.PlayerReplicationInfo.PlayerID = CurrentID++; NewBot.PlayerReplicationInfo.Team = RemoteBotConfig.GetBotTeam(BotN); RemoteBotConfig.CHIndividualize(NewBot, BotN); NewBot.ViewRotation = StartSpot.Rotation; AddDefaultInventory( NewBot ); if ( bRequireReady && (CountDown > 0) ) { NewBot.GotoState('Dying', 'WaitingForStart'); } NewBot.AirControl = AirControl; if ( (Level.NetMode != NM_Standalone) && (bNetReady || bRequireReady) ) { // replicate skins for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo != None) && P.PlayerReplicationInfo.bWaitingPlayer && P.IsA('PlayerPawn') ) { if ( NewBot.bIsMultiSkinned ) PlayerPawn(P).ClientReplicateSkins(NewBot.MultiSkins[0], NewBot.MultiSkins[1], NewBot.MultiSkins[2], NewBot.MultiSkins[3]); else PlayerPawn(P).ClientReplicateSkins(NewBot.Skin); } } } return NewBot; } Mclass BotServer expands TcpLink config(BotAPI); var config int ListenPort; var config int MaxConnections; var string gameClass; var bool bBound; var config bool bDebug; var int ConnectionCount; // configurable delimeters for strings sent to clients // currently of form (with multiple possible attributes): // "type"$ib$"identifier"$ib$as$"attrname1"$ib$"attrvalue1"$ae // as = identifies the start of an attribute var string as; // ae = attribute end var string ae; // ib = item break var string ib; //shouldn't happen event ReceivedText( string Text ) { if(bDebug) log("RecievedTest in Server - "$Text); } function BeginPlay() { Super.BeginPlay(); if(!bBound) { BindPort( ListenPort ); if(bDebug) log("BotServer bound to port "$ListenPort); Listen(); bBound = true; } } //should never happen - accepted connections should be forwarded to a botconnection event Accepted() { if(bDebug) log("Accepted connection in BotServer"); } //called everytime a new botconnection is spawned event GainedChild( Actor C ) { Super.GainedChild(C); ConnectionCount++; //BotConnection(C).Parent = self; // if too many connections, close down listen. if(MaxConnections > 0 && ConnectionCount > MaxConnections && LinkState == STATE_Listening) { if(bDebug) Log("BotServer: Too many connections - closing down Listen."); Close(); } } event LostChild( Actor C ) { Super.LostChild(C); ConnectionCount--; // if closed due to too many connections, start listening again. if(ConnectionCount <= MaxConnections && LinkState != STATE_Listening) { if(bDebug) Log("BotServer: Listening again - connections have been closed."); Listen(); } } d QtYW-dB~I-opVizServer bound to port S~r-d' C|}\?}nlED @ED?,?E,GD?,?EBD?,,D D?B,wA*A?E, ?A?E,wB*B?E, ?B?G, [ J"Ay!8"JKLNU Yj[]+4[a/!}w[*z[a!?[-'[ 6=[ q!?!E[a!G[-'[ 6=[ q!G!E x//============================================================================= // BotDomination. //============================================================================= class BotDomination extends Domination config(BotAPI); var VizServer theVizServer; var BotServer theBotServer; var bool bServerLoaded; var RemoteBotInfo RemoteBotConfig; var int NumRemoteBots; function PostBeginPlay() { Super.PostBeginPlay(); if(!bServerLoaded) { theVizServer = spawn(class'VizServer',self); theVizServer.gameClass = "BotDomination"; theBotServer = spawn(class'BotServer',self); theBotServer.gameClass = "BotDomination"; bServerLoaded = true; } RemoteBotConfig = spawn(class'RemoteBotInfo',self); RemoteBotConfig.Difficulty = BotConfig.Difficulty; } function string GetGameInfo() { local string ib, as, ae; local string outStr; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = (ib$as$ "GoalTeamScore" $ib$ GoalTeamScore $ae$ib$as$ "TimeLimit" $ib$ TimeLimit $ae$ib$as$ "MaxTeams" $ib$ MaxTeams $ae$ib$as$ "MaxTeamSize" $ib$ MaxTeamSize $ae); return outStr; } function string GetGameStatus() { local string ib, as, ae; local string outStr; local int i, j, teamNum; local Pawn P; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = "GAM"; outStr = ( outStr $ib$as$ "PlayerScores" ); for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if( !P.IsA('Spectator') ) outStr = ( outStr $ib$as$ P $ib$ P.PlayerReplicationInfo.Score $ae ); } outStr = ( outStr $ae ); outStr = ( outStr $ib$as$ "TeamScores" ); for (i=0;i 0 ) { if ( RemainingTime < 0.25 * TimeLimit ) { if ( RemainingTime < 0.1 * TimeLimit ) c = 0.8; else c = 0.4; } } if ( !bRequireReady || (CountDown <= 0) ) for ( N=Level.NavigationPointList; N!=None; N=N.nextNavigationPoint ) { CP = ControlPoint(N); if ( (CP != None) && (CP.ControllingTeam != None) && CP.bScoreReady ) { CP.ControllingTeam.Score += c; CP.Controller.PlayerReplicationInfo.Score += c; } } DomScoreEvent++; if (DomScoreEvent >= 5) { DomScoreEvent = 0; for (i=0; i<4; i++) { if (Teams[i].Score > 0) { if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogSpecialEvent("dom_score_update", i, Teams[i].Score); if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogSpecialEvent("dom_score_update", i, Teams[i].Score); } } for (i=0; i<32; i++) { PRI = GameReplicationInfo.PRIArray[i]; if (PRI != None) { if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogSpecialEvent("dom_playerscore_update", PRI.PlayerID, int(PRI.Score)); if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogSpecialEvent("dom_playerscore_update", PRI.PlayerID, int(PRI.Score)); } } } if ( GoalTeamScore > 0 ) for ( i=0; i<4; i++ ) if ( Teams[i].Score >= GoalTeamScore ) EndGame("teamscorelimit"); } //start pregame shit Super(GameInfo).Timer(); if ( bNetReady ) { if ( NumPlayers + NumRemoteBots > 0 ) ElapsedTime++; else ElapsedTime = 0; if ( ElapsedTime > NetWait ) { if ( (NumPlayers + NumBots + NumRemoteBots < 4) && NeedPlayers() ) AddBot(); else if ( (NumPlayers + NumBots + NumRemoteBots > 1) || ((NumPlayers + NumRemoteBots > 0) && (ElapsedTime > 2 * NetWait)) ) bNetReady = false; } if ( bNetReady ) { for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); return; } else { while ( NeedPlayers() ) AddBot(); bRequireReady = false; StartMatch(); } } if ( bRequireReady && (CountDown > 0) ) { while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); if ( ((NumPlayers == MaxPlayers) || (Level.NetMode == NM_Standalone)) && (RemainingBots <= 0) ) { bReady = true; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') && !P.IsA('Spectator') && !PlayerPawn(P).bReadyToPlay ) bReady = false; if ( bReady ) { StartCount = 30; CountDown--; if ( CountDown <= 0 ) StartMatch(); else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); if ( (CountDown < 11) && P.IsA('TournamentPlayer') ) TournamentPlayer(P).TimeMessage(CountDown); else PlayerPawn(P).SetProgressMessage(CountDown$CountDownMessage, 0); } } } else if ( StartCount > 8 ) { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); PlayerPawn(P).SetProgressTime(2); PlayerPawn(P).SetProgressMessage(WaitingMessage1, 0); PlayerPawn(P).SetProgressMessage(WaitingMessage2, 1); if ( PlayerPawn(P).bReadyToPlay ) PlayerPawn(P).SetProgressMessage(ReadyMessage, 2); else PlayerPawn(P).SetProgressMessage(NotReadyMessage, 2); } } else { StartCount++; if ( Level.NetMode != NM_Standalone ) StartCount = 30; } } else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) PlayStartupMessage(PlayerPawn(P)); } } else { if ( bAlwaysForceRespawn || (bForceRespawn && (Level.NetMode != NM_Standalone)) ) For ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if ( P.IsInState('Dying') && P.IsA('PlayerPawn') && P.bHidden ) PlayerPawn(P).ServerReStartPlayer(); } if ( NeedPlayers() ) AddBot(); else while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; if ( bGameEnded ) { if ( Level.TimeSeconds > EndTime + RestartWait ) RestartGame(); } else if ( !bOverTime && (TimeLimit > 0) ) { GameReplicationInfo.bStopCountDown = false; RemainingTime--; GameReplicationInfo.RemainingTime = RemainingTime; if ( RemainingTime % 60 == 0 ) GameReplicationInfo.RemainingMinute = RemainingTime; if ( RemainingTime <= 0 ) EndGame("timelimit"); } else { ElapsedTime++; GameReplicationInfo.ElapsedTime = ElapsedTime; } } } function Logout( pawn Exiting ) { ClearControl(Exiting); Super(GameInfo).Logout(Exiting); if ( Exiting.IsA('Bot') && !Exiting.IsA('RemoteBot') ) NumBots--; if ( Exiting.IsA('RemoteBot') ) NumRemoteBots--; if ( Exiting.IsA('Commander') ) NumCommanders--; if ( NeedPlayers() && !AddBot() ) RemainingBots++; if ( Exiting.IsA('Spectator') || Exiting.IsA('Commander') ) return; Teams[Exiting.PlayerReplicationInfo.Team].Size--; ClearOrders(Exiting); if ( !bGameEnded && bBalanceTeams && !bRatedGame ) ReBalance(); } function bool RestartPlayer( pawn aPlayer ) { local Bot B; local bool bResult; aPlayer.DamageScaling = aPlayer.Default.DamageScaling; B = Bot(aPlayer); if ( (B != None) && !B.IsA('RemoteBot') && (B.Orders == 'Defend') ) B.SetOrders('Freelance', None); if ( (B != None) && (!B.IsA('RemoteBot')) && TooManyBots() ) { log("Destroying bot"); aPlayer.Destroy(); return false; } bResult = Super(GameInfo).RestartPlayer(aPlayer); if ( aPlayer.IsA('TournamentPlayer') ) TournamentPlayer(aPlayer).StartSpot = LastStartSpot; return bResult; } // rebalance teams after player changes teams or leaves // find biggest and smallest teams. If 2 apart, move bot from biggest to smallest function ReBalance() { local int big, small, i, bigsize, smallsize; local Pawn P, A; local Bot B; if ( bBalancing || (NumBots == 0) ) return; big = 0; small = 0; bigsize = Teams[0].Size; smallsize = Teams[0].Size; for ( i=1; i bigsize ) { big = i; bigsize = Teams[i].Size; } else if ( Teams[i].Size < smallsize ) { small = i; smallsize = Teams[i].Size; } } bBalancing = true; while ( bigsize - smallsize > 1 ) { for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo.Team == big) && P.IsA('Bot') && !P.IsA('RemoteBot') ) { B = Bot(P); break; } if ( B != None ) { B.Health = 0; B.Died( None, 'Suicided', B.Location ); bigsize--; smallsize++; ChangeTeam(B, small); } else Break; } bBalancing = false; // re-assign orders to follower bots with no leaders for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && P.IsA('Bot') && !P.IsA('RemoteBot') && (BotReplicationInfo(P.PlayerReplicationInfo).RealOrders == 'Follow') ) { A = Pawn(Bot(P).OrderObject); if ( (A == None) || A.bDeleteMe || !A.bIsPlayer || (A.PlayerReplicationInfo.Team != P.PlayerReplicationInfo.Team) ) { Bot(P).OrderObject = None; SetBotOrders(Bot(P)); } } } //Hook in here to send damage messages may not be 100% reliable because //Mutator's MutatorTakeDamage call happens in pawn, after this. So a mutator //that changes damage will not be considered for HurtOther message function int ReduceDamage(int Damage, name DamageType, pawn injured, pawn instigatedBy) { local RemoteBot theBot; theBot = RemoteBot(instigatedBy); Damage = Super.ReduceDamage(Damage, DamageType, injured, instigatedBy); if( theBot != none) theBot.HurtOther((Damage * instigatedBy.DamageScaling), DamageType, Injured); return Damage; } function bool ChangeTeam(Pawn Other, int NewTeam) { local int i, s, DesiredTeam; local pawn APlayer, P; local teaminfo SmallestTeam; if ( bRatedGame && (Other.PlayerReplicationInfo.Team != 255) ) return false; if ( Other.PlayerReplicationInfo.Team != 255 ) { ClearOrders(Other); Teams[Other.PlayerReplicationInfo.Team].Size--; } for( i=0; i Teams[i].Size) ) { s = i; SmallestTeam = Teams[i]; } if ( bPlayersBalanceTeams ) { if ( NumBots == 1 ) { // join bot's team, because he will leave for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('Bot') && !P.IsA('RemoteBot') ) break; if ( (P != None) && (P.PlayerReplicationInfo != None) && (Teams[P.PlayerReplicationInfo.Team].Size == SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = P.PlayerReplicationInfo.Team; } else if ( (NewTeam >= MaxTeams) || (Teams[NewTeam].Size > SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = 255; } } else if ( (NewTeam >= MaxTeams) || (Teams[NewTeam].Size > SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = 255; } } if ( (NewTeam == 255) || (NewTeam >= MaxTeams) ) NewTeam = s; if ( Other.IsA('Spectator') ) { Other.PlayerReplicationInfo.Team = 255; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); return true; } if ( Other.IsA('Commander') ) { Other.PlayerReplicationInfo.Team = NewTeam; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); return true; } if ( (Other.PlayerReplicationInfo.Team == NewTeam) && bNoTeamChanges ) return false; if ( Other.IsA('TournamentPlayer') ) TournamentPlayer(Other).StartSpot = None; if (Teams[NewTeam].Size < MaxTeamSize) { AddToTeam(NewTeam, Other); return true; } if ( (SmallestTeam != None) && (SmallestTeam.Size < MaxTeamSize) ) { AddToTeam(s, Other); return true; } return false; } //Shouldn't matter - dont think it is actually called in teamgames //voided for remoteBots anyway though function SetAttractionStateFor(Bot aBot) { if ( !aBot.IsA('RemoteBot') ) { if ( aBot.Enemy != None ) { if ( !aBot.IsInState('FallBack') ) { aBot.bNoClearSpecial = true; aBot.TweenToRunning(0.1); aBot.GotoState('FallBack','SpecialNavig'); } } else if ( !aBot.IsInState('Roaming') ) { aBot.bNoClearSpecial = true; aBot.TweenToRunning(0.1); aBot.GotoState('Roaming', 'SpecialNavig'); } } } function ClearOrders(Pawn Leaving) { local Pawn P; for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('Bot') && !P.IsA('RemoteBot') && (Bot(P).OrderObject == Leaving) ) Bot(P).SetOrders('Freelance', None); } function RemoteBot AddRemoteBot(BotConnection theConnection, string clientName, int teamNum) { local RemoteBot NewBot; local NavigationPoint StartSpot, OldStartSpot; local int DesiredTeam, i, MinSize; NewBot = SpawnRemoteBot(StartSpot, theConnection); if ( NewBot == None ) { log("Failed to spawn remote bot"); return none; } NewBot.PlayerReplicationInfo.Team = teamNum; if ( clientName != "" ) NewBot.PlayerReplicationInfo.Team = teamNum; if ( bBalanceTeams && !bRatedGame ) { MinSize = Teams[0].Size; DesiredTeam = 0; for ( i=1; i= MaxTeams ) NextBotTeam = 0; } if ( bSpawnInTeamArea ) { OldStartSpot = StartSpot; StartSpot = FindPlayerStart(NewBot,255); if ( StartSpot != None ) { NewBot.SetLocation(StartSpot.Location); NewBot.SetRotation(StartSpot.Rotation); NewBot.ViewRotation = StartSpot.Rotation; NewBot.SetRotation(NewBot.Rotation); StartSpot.PlayTeleportEffect( NewBot, true ); } else StartSpot = OldStartSpot; } StartSpot.PlayTeleportEffect(NewBot, true); // Log it. if (LocalLog != None) { LocalLog.LogPlayerConnect(NewBot); LocalLog.FlushLog(); } if (WorldLog != None) { WorldLog.LogPlayerConnect(NewBot); WorldLog.FlushLog(); } NumRemoteBots++; return NewBot; } function bool ForceAddBot() { // add bot during gameplay if ( Level.NetMode != NM_Standalone ) MinPlayers = Max(MinPlayers+1, NumPlayers + NumRemoteBots + NumBots + 1); AddBot(); } function bool OneOnOne() { return ( NumPlayers + NumBots + NumRemoteBots == 2 ); } function bool NeedPlayers() { return (!bGameEnded && (NumPlayers + NumBots + NumRemoteBots < MinPlayers)); } function bool TooManyBots() { return (NumBots + NumPlayers + NumRemoteBots > MinPlayers); } function RemoteBot SpawnRemoteBot(out NavigationPoint StartSpot, BotConnection theConnection) { local RemoteBot NewBot; local int BotN; local Pawn P; BotN = RemoteBotConfig.ChooseBotInfo(); // Find a start spot. StartSpot = FindPlayerStart(None, 255); if( StartSpot == None ) { log("Could not find starting spot for RemoteBot"); return None; } // Try to spawn the bot. NewBot = Spawn(RemoteBotConfig.CHGetBotClass(BotN),,,StartSpot.Location,StartSpot.Rotation); if ( NewBot == None ) log("Couldn't spawn player at "$StartSpot); if ( NewBot != None ) { //hook up connection to socket NewBot.myConnection = theConnection; NewBot.as = theConnection.as; NewBot.ae = theConnection.ae; NewBot.ib = theConnection.ib; // Set the player's ID. NewBot.PlayerReplicationInfo.PlayerID = CurrentID++; NewBot.PlayerReplicationInfo.Team = RemoteBotConfig.GetBotTeam(BotN); RemoteBotConfig.CHIndividualize(NewBot, BotN); NewBot.ViewRotation = StartSpot.Rotation; AddDefaultInventory( NewBot ); if ( bRequireReady && (CountDown > 0) ) { NewBot.GotoState('Dying', 'WaitingForStart'); } NewBot.AirControl = AirControl; if ( (Level.NetMode != NM_Standalone) && (bNetReady || bRequireReady) ) { // replicate skins for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo != None) && P.PlayerReplicationInfo.bWaitingPlayer && P.IsA('PlayerPawn') ) { if ( NewBot.bIsMultiSkinned ) PlayerPawn(P).ClientReplicateSkins(NewBot.MultiSkins[0], NewBot.MultiSkins[1], NewBot.MultiSkins[2], NewBot.MultiSkins[3]); else PlayerPawn(P).ClientReplicateSkins(NewBot.Skin); } } } return NewBot; } R//============================================================================= // DeathMatchPlus. //============================================================================= class BotDeathMatchPlus extends DeathMatchPlus config(BotAPI); var VizServer theVizServer; var BotServer theBotServer; var bool bServerLoaded; var RemoteBotInfo RemoteBotConfig; var int NumRemoteBots; function PostBeginPlay() { Super.PostBeginPlay(); if(!bServerLoaded) { theVizServer = spawn(class'VizServer',self); theVizServer.gameClass = "BotDeathMatchPlus"; theBotServer = spawn(class'BotServer',self); theBotServer.gameClass = "BotDeathMatchPlus"; bServerLoaded = true; } RemoteBotConfig = spawn(class'RemoteBotInfo',self); RemoteBotConfig.Difficulty = BotConfig.Difficulty; } function string GetGameInfo() { local string ib, as, ae; local string outStr; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = (ib$as$ "FragLimit" $ib$ FragLimit $ae$ib$as$ "TimeLimit" $ib$ TimeLimit $ae); return outStr; } function string GetGameStatus() { local string ib, as, ae; local string outStr; local Pawn P; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = "GAM"; outStr = ( outStr $ib$as$ "PlayerScores" ); for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if( !P.IsA('Spectator') ) outStr = ( outStr $ib$as$ P $ib$ P.PlayerReplicationInfo.Score $ae ); } outStr = ( outStr $ae ); return outStr; } function RemoteBot SpawnRemoteBot(out NavigationPoint StartSpot, BotConnection theConnection) { local RemoteBot NewBot; local int BotN; local Pawn P; BotN = RemoteBotConfig.ChooseBotInfo(); // Find a start spot. StartSpot = FindPlayerStart(None, 255); if( StartSpot == None ) { log("Could not find starting spot for RemoteBot"); return None; } // Try to spawn the bot. NewBot = Spawn(RemoteBotConfig.CHGetBotClass(BotN),,,StartSpot.Location,StartSpot.Rotation); if ( NewBot == None ) log("Couldn't spawn player at "$StartSpot); if ( NewBot != None ) { //hook up connection to socket NewBot.myConnection = theConnection; NewBot.as = theConnection.as; NewBot.ae = theConnection.ae; NewBot.ib = theConnection.ib; // Set the player's ID. NewBot.PlayerReplicationInfo.PlayerID = CurrentID++; NewBot.PlayerReplicationInfo.Team = RemoteBotConfig.GetBotTeam(BotN); RemoteBotConfig.CHIndividualize(NewBot, BotN); NewBot.ViewRotation = StartSpot.Rotation; AddDefaultInventory( NewBot ); if ( bRequireReady && (CountDown > 0) ) { NewBot.GotoState('Dying', 'WaitingForStart'); } NewBot.AirControl = AirControl; if ( (Level.NetMode != NM_Standalone) && (bNetReady || bRequireReady) ) { // replicate skins for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo != None) && P.PlayerReplicationInfo.bWaitingPlayer && P.IsA('PlayerPawn') ) { if ( NewBot.bIsMultiSkinned ) PlayerPawn(P).ClientReplicateSkins(NewBot.MultiSkins[0], NewBot.MultiSkins[1], NewBot.MultiSkins[2], NewBot.MultiSkins[3]); else PlayerPawn(P).ClientReplicateSkins(NewBot.Skin); } } } return NewBot; } //Same as GameInfo, but change the skin function bool ChangeTeam(Pawn Other, int N) { local string SkinName, FaceName; Other.PlayerReplicationInfo.Team = N; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); Other.static.GetMultiSkin(Other, SkinName, FaceName); Other.static.SetMultiSkin(Other, SkinName, FaceName, N); return true; } function bool ForceAddBot() { // add bot during gameplay if ( Level.NetMode != NM_Standalone ) MinPlayers = Max(MinPlayers+1, NumPlayers + NumRemoteBots + NumBots + 1); AddBot(); } function bool OneOnOne() { return ( NumPlayers + NumBots + NumRemoteBots == 2 ); } function bool NeedPlayers() { return (!bGameEnded && (NumPlayers + NumBots + NumRemoteBots < MinPlayers)); } function bool TooManyBots() { return (NumBots + NumPlayers + NumRemoteBots > MinPlayers); } //Controls gamestart - must have at least one player/remote bot in game, //then waits for CountDown length (note that in standalone (i.e. practice //session games) CountDown is set to 1 automatically. function Timer() { local Pawn P; local bool bReady; local int M; Super(GameInfo).Timer(); if ( bNetReady ) { if ( NumPlayers + NumRemoteBots > 0 ) ElapsedTime++; else ElapsedTime = 0; if ( ElapsedTime > NetWait ) { if ( (NumPlayers + NumBots + NumRemoteBots < 4) && NeedPlayers() ) AddBot(); else if ( (NumPlayers + NumBots + NumRemoteBots > 1) || ((NumPlayers + NumRemoteBots > 0) && (ElapsedTime > 2 * NetWait)) ) bNetReady = false; } if ( bNetReady ) { for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); return; } else { while ( NeedPlayers() ) AddBot(); bRequireReady = false; StartMatch(); } } if ( bRequireReady && (CountDown > 0) ) { while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); if ( ((NumPlayers == MaxPlayers) || (Level.NetMode == NM_Standalone)) && (RemainingBots <= 0) ) { bReady = true; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') && !P.IsA('Spectator') && !PlayerPawn(P).bReadyToPlay ) bReady = false; if ( bReady ) { StartCount = 30; CountDown--; if ( CountDown <= 0 ) StartMatch(); else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); if ( (CountDown < 11) && P.IsA('TournamentPlayer') ) TournamentPlayer(P).TimeMessage(CountDown); else PlayerPawn(P).SetProgressMessage(CountDown$CountDownMessage, 0); } } } else if ( StartCount > 8 ) { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); PlayerPawn(P).SetProgressTime(2); PlayerPawn(P).SetProgressMessage(WaitingMessage1, 0); PlayerPawn(P).SetProgressMessage(WaitingMessage2, 1); if ( PlayerPawn(P).bReadyToPlay ) PlayerPawn(P).SetProgressMessage(ReadyMessage, 2); else PlayerPawn(P).SetProgressMessage(NotReadyMessage, 2); } } else { StartCount++; if ( Level.NetMode != NM_Standalone ) StartCount = 30; } } else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) PlayStartupMessage(PlayerPawn(P)); } } else { if ( bAlwaysForceRespawn || (bForceRespawn && (Level.NetMode != NM_Standalone)) ) For ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if ( P.IsInState('Dying') && P.IsA('PlayerPawn') && P.bHidden ) PlayerPawn(P).ServerReStartPlayer(); } if ( NeedPlayers() ) AddBot(); else while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; if ( bGameEnded ) { if ( Level.TimeSeconds > EndTime + RestartWait ) RestartGame(); } else if ( !bOverTime && (TimeLimit > 0) ) { GameReplicationInfo.bStopCountDown = false; RemainingTime--; GameReplicationInfo.RemainingTime = RemainingTime; if ( RemainingTime % 60 == 0 ) GameReplicationInfo.RemainingMinute = RemainingTime; if ( RemainingTime <= 0 ) EndGame("timelimit"); } else { ElapsedTime++; GameReplicationInfo.ElapsedTime = ElapsedTime; } } } //Hook in here to send damage messages may not be 100% reliable because //Mutator's MutatorTakeDamage call happens in pawn, after this. So a mutator //that changes damage will not be considered for HurtOther message function int ReduceDamage(int Damage, name DamageType, pawn injured, pawn instigatedBy) { local RemoteBot theBot; theBot = RemoteBot(instigatedBy); Damage = Super.ReduceDamage(Damage, DamageType, injured, instigatedBy); if( theBot != none) theBot.HurtOther((Damage * instigatedBy.DamageScaling), DamageType, Injured); return Damage; } function bool RestartPlayer( pawn aPlayer ) { local Bot B; local bool bResult; aPlayer.DamageScaling = aPlayer.Default.DamageScaling; B = Bot(aPlayer); if ( (B != None) && (!B.IsA('RemoteBot')) && TooManyBots() ) { log("Destroying bot"); aPlayer.Destroy(); return false; } bResult = Super(GameInfo).RestartPlayer(aPlayer); if ( aPlayer.IsA('TournamentPlayer') ) TournamentPlayer(aPlayer).StartSpot = LastStartSpot; return bResult; } function RemoteBot AddRemoteBot(BotConnection theConnection, string clientName, int teamNum) { local RemoteBot NewBot; local NavigationPoint StartSpot; NewBot = SpawnRemoteBot(StartSpot, theConnection); if ( NewBot == None ) { log("Failed to spawn remote bot."); return none; } NewBot.PlayerReplicationInfo.Team = teamNum; if ( clientName != "" ) NewBot.PlayerReplicationInfo.Team = teamNum; StartSpot.PlayTeleportEffect(NewBot, true); NewBot.PlayerReplicationInfo.bIsABot = True; // Log it. if (LocalLog != None) { LocalLog.LogPlayerConnect(NewBot); LocalLog.FlushLog(); } if (WorldLog != None) { WorldLog.LogPlayerConnect(NewBot); WorldLog.FlushLog(); } NumRemoteBots++; return NewBot; } function Logout(pawn Exiting) { Super(GameInfo).Logout(Exiting); if ( Exiting.IsA('Bot') && !Exiting.IsA('RemoteBot') ) NumBots--; if ( Exiting.IsA('RemoteBot') ) NumRemoteBots--; if ( Exiting.IsA('Commander') ) NumCommanders--; if ( NeedPlayers() && !AddBot() ) RemainingBots++; } p//============================================================================= // BotAPIConfigMenu. //============================================================================= class BotAPIConfigMenu expands UWindowFramedWindow; Nclass BotConnection expands TcpLink config(BotAPI); var string ReceivedData; var string RecievedArgs[9]; var string RecievedVals[9]; //used to store info inside function where local wont work //set property text dosent seem to work with a local var actor tempActor; var bool tempBool; var BotServer Parent; var RemoteBot theBot; // set true for verbose debug logs var config bool bDebug; // set true for iterative mode var config bool bIterative; // delay between visionUpdates var config float visionTime; // delimeters for strings sent to clients. set to match those of the server // as = identifies the start of an attribute var string as; // ae = attribute end var string ae; // ib = item break var string ib; //------------Message Types--------------------------- // Each message appears on a seperate line. The first item // of each message is the type identifier. It is a three // letter code identifing what the message contains. // Used types are: // (Asynchronous messages) // FIN - game ended // FAL - bot just hit a dropoff // NFO - info about gametype. cue to register self // AIN - added inventory. Bot got new inventory item // VMS - recieved message from global chat channel // VMT - recieved message from team chat channel // VMG - recieved tokenized message // ZCF - foot changed zones // ZCH - head changed zones // ZCB - bot changed zones // CWP - changed weapon // WAL - collided with a wall // BMP - bumped another actor // HRP - hear pickup // HRN - hear noise // SEE - see player - !!!DEPRICATED // PRJ - incoming projectile // KIL - some other player died // DIE - bot died // DAM - took damage // HIT - hurt another player // PTH - a series of nodes in response to a getpath call // RCH - a bool result of a checkreach call // (Synchronous messages) // PLR - see another player // INV - see an inventory item (or weapon) // NAV - see a navigation point // DOM - see a domination point // FLG - see a flag // MOV - see a mover // END - end of a vision batch // BEG - begin of a vision batch // SLF - random information about bots state // GAM - random information about game state //-------------------------------------------------- function PostBeginPlay() { Parent = BotServer(Owner); ib = Parent.ib; as = Parent.as; ae = Parent.ae; if(bDebug) log("Spawned BotConnection"); } //Socket established event Accepted() { local string gameInfoStr, levelName; local int i; if(bDebug) log("Accepted BotConnection" @ self); //no clean way to do this since gametypes are not derived from //a common ancestor switch(Parent.gameClass) { case "BotTeamGamePlus": gameInfoStr = BotTeamGamePlus(Level.Game).GetGameInfo(); break; case "BotDeathMatchPlus": gameInfoStr = BotDeathMatchPlus(Level.Game).GetGameInfo(); break; case "BotDomination": gameInfoStr = BotDomination(Level.Game).GetGameInfo(); break; case "BotCTF": gameInfoStr = BotCTF(Level.Game).GetGameInfo(); break; } levelName = string(Level); i = InStr(Caps(levelName), ".LEVELINFO"); if(i != -1) levelName = Left(levelName, i); SendLine("NFO" $ib$as$ "Gametype" $ib$ Parent.gameClass $ae$ib$as$ "Level" $ib$ levelName $ae$ gameInfoStr); gotoState('monitoring','WaitingForInit'); } //InitRecieved from client event InitRecieved() { local string clientName; local string teamString; local int teamNum; clientName = GetArgVal("Name"); teamString = GetArgVal("Team"); if( teamString == "" ) teamNum = 255; else teamNum = int(teamString); //no clean way to do this since gametypes are not derived from //a common ancestor that has AddRemoteBot switch(Parent.gameClass) { case "BotTeamGamePlus": theBot = BotTeamGamePlus(Level.Game).AddRemoteBot(self, clientName, teamNum); break; case "BotDeathMatchPlus": theBot = BotDeathMatchPlus(Level.Game).AddRemoteBot(self, clientName, teamNum); break; case "BotDomination": theBot = BotDomination(Level.Game).AddRemoteBot(self, clientName, teamNum); break; case "BotCTF": theBot = BotCTF(Level.Game).AddRemoteBot(self, clientName, teamNum); break; } // broadcast a welcome message. Level.Game.BroadcastMessage( theBot.PlayerReplicationInfo.PlayerName$Level.Game.EnteredMessage, false ); gotoState('monitoring','Running'); } //Closed on other end event Closed() { theBot.Destroy(); Destroy(); } //Recieve info - parse into lines and call RecievedLine event ReceivedText( string Text ) { local int i; local string S; if(bDebug) log("Recieved - "$Text); ReceivedData = ReceivedData $ Text; // remove a LF which arrived in a new packet // and thus didn't get cleaned up by the code below if(Left(ReceivedData, 1) == Chr(10)) ReceivedData = Mid(ReceivedData, 1); i = InStr(ReceivedData, Chr(13)); while(i != -1) { S = Left(ReceivedData, i); i++; // check for any LF following the CR. if(Mid(ReceivedData, i, 1) == Chr(10)) i++; ReceivedData = Mid(ReceivedData, i); ReceivedLine(S); if(LinkState != STATE_Connected) return; i = InStr(ReceivedData, Chr(13)); } } //Here is where we handle incoming commands /* Commands expected to look like: {RUN {Argument value} {Arg value}...} Currently had coded to take no more than 9 args Command type and arguments can be any length, but first space terminates the name. Values can have spaces or any other kind of character. */ function ReceivedLine(string S) { local string cmdType, argBody, rem; local int endloc, wordsplit, attrNum; local name curBotState; if(bDebug) log(S); if( theBot != none ) { curBotState = theBot.GetStateName(); if( curBotState == 'Dying' || curBotState == 'GameEnded') return; } wordsplit = InStr(S,ib); if( wordsplit == -1) wordsplit = Len(S); cmdType = left(S,wordsplit); rem = mid(S,InStr(S,as)); attrNum = 0; //iterate through attr/val pairs, storring them in the //parallel arrays RecievedArgs and RecievedVals while(attrNum < 9 && rem != "") { endloc = InStr(rem,ae); argBody = mid(rem,1,(endloc - 1)); wordsplit = InStr(argBody,ib); RecievedArgs[attrNum] = left(argBody,wordsplit); RecievedVals[attrNum] = mid(argBody,(wordsplit + 1)); rem = mid(rem,1); //advance rem = mid(rem,InStr(rem,as)); attrNum++; } cmdType = Caps(cmdType); ProcessAction(cmdType); } function string GetArgVal(string argName) { local string argValue; local int i; while (i < 9 && RecievedArgs[i] != "") { if (RecievedArgs[i] ~= argName) return RecievedVals[i]; i++; } return ""; } function ParseVector(out vector v, string vecName) { local int i; local string rem; local float x,y,z; local string delim; delim = ib; rem = GetArgVal(vecName); if(rem != "") { if( InStr(rem,delim) == -1 ) delim = ","; i = InStr(rem,delim); v.X = float(left(rem,i)); rem = mid(rem,i+1); i = InStr(rem,delim); v.Y = float(left(rem,i)); v.Z = float(mid(rem,i+1)); } else { v.x = float( GetArgVal("x") ); v.y = float( GetArgVal("y") ); v.z = float( GetArgVal("z") ); } } function ParseRot(out rotator rot) { local int i; local string rem; local float y,p,r; local string delim; delim = ib; rem = GetArgVal("Rotation"); if(rem != "") { if( InStr(rem,delim) == -1 ) delim = ","; i = InStr(rem,delim); rot.Pitch = float(left(rem,i)); rem = mid(rem,i+1); i = InStr(rem,delim); rot.Yaw = float(left(rem,i)); rot.Roll = float(mid(rem,i+1)); } else { rot.Pitch = float( GetArgVal("pitch") ); rot.Yaw = float( GetArgVal("yaw") ); rot.Roll = float( GetArgVal("roll") ); } } function ProcessAction(string cmdType) { local int i; local vector v, v2; local bool boolResult; local string target, rotTarg, id, outBuf, focusTarg; local rotator r; if(bDebug) log("comandType:"@cmdType); if (bIterative) Level.Pauser=""; switch(cmdType) { case "TEST": theBot.GotoState('Startup', 'Test'); break; case "INIT": InitRecieved(); break; case "INCH": //test function /* must deal with target, focus and destination */ theBot.StopWaiting(); theBot.myDestination = (100 * vector(theBot.Rotation)) + theBot.Location; theBot.GotoState('Startup', 'Move'); break; case "SETWALK": target = GetArgVal("Walk"); SetPropertyText("tempBool",target); theBot.bIsWalking = tempBool; break; case "STOP": theBot.GotoState('Startup', 'Begin'); break; case "JUMP": theBot.RemoteJump(); break; case "RUNTO": target = GetArgVal("Target"); if(target == "") { ParseVector(v,"Location"); theBot.myDestination = v; //theBot.RemoteDestination = none; theBot.GotoState('Startup', 'Move'); } else { SetPropertyText("tempActor",target); if( tempActor != none && theBot.FastTrace(tempActor.Location) && theBot.inFront(tempActor.Location) ) { //theBot.RemoteDestination = none; //zero out myDestination theBot.myDestination = tempActor.Location; theBot.GotoState('Startup', 'Move'); } } break; case "STRAFE": ParseVector(v,"Location"); theBot.myDestination = v; focusTarg = GetArgVal("Target"); if(focusTarg == "") { ParseVector(v2,"Focus"); theBot.myFocus = v2; theBot.RemoteFocus = none; } else { SetPropertyText("tempActor",focusTarg); if( tempActor != none && theBot.FastTrace(tempActor.Location) && theBot.inFront(tempActor.Location) ) { theBot.RemoteFocus = tempActor; //zero out myFocus theBot.myFocus = v2; } } theBot.StopWaiting(); theBot.GotoState('Startup', 'Strafe'); break; case "SHOOT": target = GetArgVal("Target"); ParseVector(v,"Location"); theBot.SetPropertyText("Enemy",target); theBot.SetPropertyText("RemoteEnemy",target); theBot.StopWaiting(); theBot.myTarget = v; target = GetArgVal("Alt"); SetPropertyText("tempBool",target); theBot.RemoteFireWeapon(tempBool); break; case "CHANGEWEAPON": target = GetArgVal("ID"); if( target ~= "best" ) { theBot.SwitchToBestWeapon(); } else { SetPropertyText("tempActor",target); if(tempActor != none) { theBot.PendingWeapon = Weapon(tempActor); if ( theBot.Weapon == None ) theBot.ChangedWeapon(); else if ( theBot.Weapon != theBot.PendingWeapon ) theBot.Weapon.PutDown(); } } break; case "STOPSHOOT": theBot.StopWaiting(); theBot.HaltFiring(); break; case "CHECKREACH": target = GetArgVal("Target"); id = GetArgVal("id"); if(target == "") { ParseVector(v,"Location"); boolResult = theBot.pointReachable(v); sendLine("RCH" $ib$as$ "ID" $ib$ id $ae$ib$as$ "Reachable" $ib$ boolResult $ae$ib$as$ "From" $ib$ theBot.Location $ae); } else { SetPropertyText("tempActor",target); if( tempActor != none && theBot.FastTrace(tempActor.Location) && theBot.inFront(tempActor.Location) ) { boolResult = theBot.actorReachable(tempActor); sendLine("RCH" $ib$as$ "ID" $ib$ id $ae$ib$as$ "Reachable" $ib$ boolResult $ae$ib$as$ "From" $ib$ theBot.Location $ae$ib$as$ "To" $ib$ tempActor.Location $ae); } } break; case "TURNTO": target = GetArgVal("Target"); if(target == "") { ParseRot(r); if(r.Yaw == 0 && r.Pitch == 0 && r.Roll == 0) { //no target or rotation defined ParseVector(v,"Location"); theBot.myFocus = v; theBot.RemoteFocus = none; } else { //no target, yes rotation theBot.myFocus = theBot.Location + ( vector(r) * 1000); theBot.RemoteFocus = none; } } else { //target defined SetPropertyText("tempActor",target); if( tempActor != none && theBot.FastTrace(tempActor.Location) && theBot.inFront(tempActor.Location) ) { theBot.RemoteFocus = tempActor; //zero out myFocus theBot.myFocus = v; } } theBot.StopWaiting(); theBot.GotoState('Startup', 'Turning'); break; case "ROTATE": target = GetArgVal("Axis"); r = theBot.Rotation; i = int(GetArgVal("Amount")); if(target == "Vertical") { r.Pitch = r.Pitch + i; } else { r.Yaw = r.Yaw + i; } theBot.myFocus = theBot.Location + ( vector(r) * 1000); theBot.RemoteFocus = none; theBot.StopWaiting(); theBot.GotoState('Startup', 'Turning'); break; case "TRACK": target = GetArgVal("Target"); if(target != "") { SetPropertyText("tempActor",target); if( theBot.FastTrace(tempActor.Location) && theBot.inFront(tempActor.Location) ) { theBot.RemoteFocus = tempActor; theBot.StopWaiting(); theBot.GotoState('Startup', 'Tracking'); } } break; case "GETPATH": //clear the old path for ( i=0; i<16; i++ ) { if ( theBot.RouteCache[i] == None ) break; else { theBot.RouteCache[i] = None; } } ParseVector(v,"Location"); theBot.FindPathTo(v); id = GetArgVal("id"); outBuf = "PTH"$ib$as$"ID"$ib$id$ae; for ( i=0; i<16; i++ ) { if ( theBot.RouteCache[i] == None ) break; else { outBuf = outBuf$ib$as$i$ib$theBot.RouteCache[i]$ib$theBot.RouteCache[i].Location$ae; } } SendLine(outBuf); break; case "MESSAGE": //Note - currently only allow messages under 256 chars target = GetArgVal("Text"); boolResult = bool(GetArgVal("Global")); if(target != "") { // @ preceding message makes it global. dont ask. not my code if(boolResult) theBot.TeamBroadcast("@"$target); else theBot.TeamBroadcast(target); } break; case "PING": SendLine("Pong"); break; } } //Send a line to the client function SendLine(string Text, optional bool bNoCRLF) { if(bDebug) log(" Sending: "$Text); if(bNoCRLF) SendText(Text); else SendText(Text$Chr(13)$Chr(10)); } //Concat two strings togeather with our list bookends function string MakeItem(string first, string second) { return (as$first$ib$second$ae); } //fire right up into the loop for sending updates auto state monitoring { Begin: WaitingForInit: sleep(5.0); goto 'WaitingForInit'; Running: if(theBot != none && Level.Pauser == "" && !theBot.IsInState('GameEnded') && !theBot.IsInState('Dying')) { SendLine("BEG" $ib$as$ "Time" $ib$ Level.TimeSeconds $ae); //no clean way to do this since gametypes are not derived from //a common ancestor that has AddRemoteBot switch(Parent.gameClass) { case "BotTeamGamePlus": sendLine( BotTeamGamePlus(Level.Game).GetGameStatus() ); break; case "BotDeathMatchPlus": sendLine( BotDeathMatchPlus(Level.Game).GetGameStatus() ); break; case "BotDomination": sendLine( BotDomination(Level.Game).GetGameStatus() ); break; case "BotCTF": sendLine( BotCTF(Level.Game).GetGameStatus(theBot) ); break; } theBot.checkSelf(); theBot.checkVision(); SendLine("END" $ib$as$ "Time" $ib$ Level.TimeSeconds $ae); } if (bIterative) Level.Pauser=theBot.PlayerReplicationInfo.PlayerName; sleep(visionTime); goto 'Running'; } ND|W 0C--C ON]; 0C--C PLc o/JT%m$$$m /f  BBHCHC QzKn, YC z%Qz,zzCze:C,Oc-C--C-#vS+wA*A- -WwB*B- - S//============================================================================= // BotAPIConfigMenuItem. //============================================================================= class BotAPIConfigMenuItem expands UMenuModMenuItem; // Called when the menu item is chosen function Execute() { MenuItem.Owner.Root.CreateWindow(class'BotAPIConfigMenu', (MenuItem.Owner.Root.WinWidth/2 - 100), (MenuItem.Owner.Root.WinHeight/2 - 100), 200, 152); } R},TOcC=cC T{(*JT, v16JTJT Uo[ -A-pSet BalanceTeams to: T -  VM2 -B-  Wu X@]d] - @zz X$@ AAoU RBMU [  Sb_2 ZZє;aGնmo ;aGնmo ;aGնmo DZ 2z]BotAPI Mutator Optionsx]Set listen port for BotAPI.g//============================================================================= // BotAPIConfigMenuCW. //============================================================================= class BotAPIConfigMenuCW expands UWindowDialogClientWindow; var UWindowSmallCloseButton CloseButton; var UWindowEditControl PortBox; var UWindowLabelControl Description; function Created() { Super.Created(); CloseButton = UWindowSmallCloseButton(CreateWindow(class'UWindowSmallCloseButton', WinWidth-48, WinHeight-19, 48, 16)); //Description = UWindowLabelControl(CreateControl(class'UWindowLabelControl', 10, 15, 30, 15); //Description.SetText("Port to bind:"); //Description.SetFont(F_Normal); PortBox = UWindowEditControl(CreateControl(class'UWindowEditControl', 10, WinHeight-66, WinWidth, 16)); //PortBox = UWindowEditControl(CreateControl(class'UWindowEditControl', 0, WinHeight-16, WinWidth, 16)); PortBox.SetMaxLength(5); PortBox.SetNumericOnly(true); PortBox.SetNumericFloat(false); PortBox.SetFont(F_Normal); PortBox.SetValue("3000"); } function Close(optional bool bByParent) { class'BotServer'.default.ListenPort = int(PortBox.GetValue()); Super.Close(bByParent); } Lu//============================================================================= // BotCTF. //============================================================================= class BotCTF extends CTFGame config(BotAPI); var VizServer theVizServer; var BotServer theBotServer; var bool bServerLoaded; var RemoteBotInfo RemoteBotConfig; var int NumRemoteBots; function PostBeginPlay() { Super.PostBeginPlay(); if(!bServerLoaded) { theVizServer = spawn(class'VizServer',self); theVizServer.gameClass = "BotCTF"; theBotServer = spawn(class'BotServer',self); theBotServer.gameClass = "BotCTF"; bServerLoaded = true; } RemoteBotConfig = spawn(class'RemoteBotInfo',self); RemoteBotConfig.Difficulty = BotConfig.Difficulty; } function string GetGameInfo() { local string ib, as, ae; local string outStr; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = (ib$as$ "GoalTeamScore" $ib$ GoalTeamScore $ae$ib$as$ "TimeLimit" $ib$ TimeLimit $ae$ib$as$ "MaxTeams" $ib$ MaxTeams $ae$ib$as$ "MaxTeamSize" $ib$ MaxTeamSize $ae); return outStr; } function string GetGameStatus(RemoteBot thebot) { local string ib, as, ae; local string outStr; local int i, j, teamNum; local Pawn P; local CTFFlag MyFlag; ib = theBotServer.ib; as = theBotServer.as; ae = theBotServer.ae; outStr = "GAM"; outStr = ( outStr $ib$as$ "PlayerScores" ); for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if( !P.IsA('Spectator') ) outStr = ( outStr $ib$as$ P $ib$ P.PlayerReplicationInfo.Score $ae ); } outStr = ( outStr $ae ); outStr = ( outStr $ib$as$ "TeamScores" ); for (i=0;i 0 ) ElapsedTime++; else ElapsedTime = 0; if ( ElapsedTime > NetWait ) { if ( (NumPlayers + NumBots + NumRemoteBots < 4) && NeedPlayers() ) AddBot(); else if ( (NumPlayers + NumBots + NumRemoteBots > 1) || ((NumPlayers + NumRemoteBots > 0) && (ElapsedTime > 2 * NetWait)) ) bNetReady = false; } if ( bNetReady ) { for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); return; } else { while ( NeedPlayers() ) AddBot(); bRequireReady = false; StartMatch(); } } if ( bRequireReady && (CountDown > 0) ) { while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') ) PlayerPawn(P).SetProgressTime(2); if ( ((NumPlayers == MaxPlayers) || (Level.NetMode == NM_Standalone)) && (RemainingBots <= 0) ) { bReady = true; for (P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') && !P.IsA('Spectator') && !PlayerPawn(P).bReadyToPlay ) bReady = false; if ( bReady ) { StartCount = 30; CountDown--; if ( CountDown <= 0 ) StartMatch(); else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); if ( (CountDown < 11) && P.IsA('TournamentPlayer') ) TournamentPlayer(P).TimeMessage(CountDown); else PlayerPawn(P).SetProgressMessage(CountDown$CountDownMessage, 0); } } } else if ( StartCount > 8 ) { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); PlayerPawn(P).SetProgressTime(2); PlayerPawn(P).SetProgressMessage(WaitingMessage1, 0); PlayerPawn(P).SetProgressMessage(WaitingMessage2, 1); if ( PlayerPawn(P).bReadyToPlay ) PlayerPawn(P).SetProgressMessage(ReadyMessage, 2); else PlayerPawn(P).SetProgressMessage(NotReadyMessage, 2); } } else { StartCount++; if ( Level.NetMode != NM_Standalone ) StartCount = 30; } } else { for ( P = Level.PawnList; P!=None; P=P.nextPawn ) if ( P.IsA('PlayerPawn') ) PlayStartupMessage(PlayerPawn(P)); } } else { if ( bAlwaysForceRespawn || (bForceRespawn && (Level.NetMode != NM_Standalone)) ) For ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if ( P.IsInState('Dying') && P.IsA('PlayerPawn') && P.bHidden ) PlayerPawn(P).ServerReStartPlayer(); } if ( NeedPlayers() ) AddBot(); else while ( (RemainingBots > 0) && AddBot() ) RemainingBots--; if ( bGameEnded ) { if ( Level.TimeSeconds > EndTime + RestartWait ) RestartGame(); } else if ( !bOverTime && (TimeLimit > 0) ) { GameReplicationInfo.bStopCountDown = false; RemainingTime--; GameReplicationInfo.RemainingTime = RemainingTime; if ( RemainingTime % 60 == 0 ) GameReplicationInfo.RemainingMinute = RemainingTime; if ( RemainingTime <= 0 ) EndGame("timelimit"); } else { ElapsedTime++; GameReplicationInfo.ElapsedTime = ElapsedTime; } } } function Logout( pawn Exiting ) { if ( Exiting.PlayerReplicationInfo.HasFlag != None ) CTFFlag(Exiting.PlayerReplicationInfo.HasFlag).SendHome(); Super(GameInfo).Logout(Exiting); if ( Exiting.IsA('Bot') && !Exiting.IsA('RemoteBot') ) NumBots--; if ( Exiting.IsA('RemoteBot') ) NumRemoteBots--; if ( Exiting.IsA('Commander') ) NumCommanders--; if ( NeedPlayers() && !AddBot() ) RemainingBots++; if ( Exiting.IsA('Spectator') || Exiting.IsA('Commander') ) return; Teams[Exiting.PlayerReplicationInfo.Team].Size--; ClearOrders(Exiting); if ( !bGameEnded && bBalanceTeams && !bRatedGame ) ReBalance(); } function bool RestartPlayer( pawn aPlayer ) { local NavigationPoint N; local int num; local float totalWeight, selection, partialWeight; local bool bResult, bPowerPlay; local bot B; local Pawn P; aPlayer.DamageScaling = aPlayer.Default.DamageScaling; if ( (B != None) && (!B.IsA('RemoteBot')) && TooManyBots() ) { log("Destroying bot"); aPlayer.Destroy(); return false; } bResult = Super(GameInfo).RestartPlayer(aPlayer); if ( aPlayer.IsA('TournamentPlayer') ) TournamentPlayer(aPlayer).StartSpot = LastStartSpot; B = Bot(aPlayer); if ( B == None ) return bResult; B.AlternatePath = None; if ( B.bPowerPlay || (BotReplicationInfo(B.PlayerReplicationInfo).RealOrders == 'Defend') ) { // if bot only team and already one defender, 50% chance of powerplay for this guy if defender if ( FRand() < 0.5 ) { B.bPowerPlay = false; B.SetOrders('Defend', None, true); } else { // check for bot only team and already a valid defender for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if ( P.bIsPlayer && (P.PlayerReplicationInfo.Team == B.PlayerReplicationInfo.Team) ) { if ( P.IsA('PlayerPawn') ) { bPowerPlay = false; break; } else if ( P.IsA('Bot') && (Bot(P).Orders == 'Defend') ) bPowerPlay = true; } } if ( bPowerPlay ) { B.bPowerPlay = true; B.SetOrders('Attack', None, true); } } } if ( BotReplicationInfo(B.PlayerReplicationInfo).RealOrders != 'Attack' ) return bResult; if ( FRand() < 0.8 ) { for ( N=Level.NavigationPointList; N!=None; N=N.nextNavigationPoint ) if ( N.IsA('AlternatePath') && (AlternatePath(N).team != B.PlayerReplicationInfo.team) && !AlternatePath(N).bReturnOnly ) TotalWeight += AlternatePath(N).SelectionWeight; selection = FRand() * TotalWeight; for ( N=Level.NavigationPointList; N!=None; N=N.nextNavigationPoint ) if ( N.IsA('AlternatePath') && (AlternatePath(N).team != B.PlayerReplicationInfo.team) ) { B.AlternatePath = AlternatePath(N); PartialWeight += AlternatePath(N).SelectionWeight; if ( PartialWeight > selection ) break; } } return bResult; } // rebalance teams after player changes teams or leaves // find biggest and smallest teams. If 2 apart, move bot from biggest to smallest function ReBalance() { local int big, small, i, bigsize, smallsize; local Pawn P, A; local Bot B; if ( bBalancing || (NumBots == 0) ) return; big = 0; small = 0; bigsize = Teams[0].Size; smallsize = Teams[0].Size; for ( i=1; i bigsize ) { big = i; bigsize = Teams[i].Size; } else if ( Teams[i].Size < smallsize ) { small = i; smallsize = Teams[i].Size; } } bBalancing = true; while ( bigsize - smallsize > 1 ) { for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo.Team == big) && P.IsA('Bot') && !P.IsA('RemoteBot') ) { B = Bot(P); break; } if ( B != None ) { B.Health = 0; B.Died( None, 'Suicided', B.Location ); bigsize--; smallsize++; ChangeTeam(B, small); } else Break; } bBalancing = false; // re-assign orders to follower bots with no leaders for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && P.IsA('Bot') && !P.IsA('RemoteBot') && (BotReplicationInfo(P.PlayerReplicationInfo).RealOrders == 'Follow') ) { A = Pawn(Bot(P).OrderObject); if ( (A == None) || A.bDeleteMe || !A.bIsPlayer || (A.PlayerReplicationInfo.Team != P.PlayerReplicationInfo.Team) ) { Bot(P).OrderObject = None; SetBotOrders(Bot(P)); } } } //Hook in here to send damage messages may not be 100% reliable because //Mutator's MutatorTakeDamage call happens in pawn, after this. So a mutator //that changes damage will not be considered for HurtOther message function int ReduceDamage(int Damage, name DamageType, pawn injured, pawn instigatedBy) { local RemoteBot theBot; theBot = RemoteBot(instigatedBy); Damage = Super.ReduceDamage(Damage, DamageType, injured, instigatedBy); if( theBot != none) theBot.HurtOther((Damage * instigatedBy.DamageScaling), DamageType, Injured); return Damage; } function bool ChangeTeam(Pawn Other, int NewTeam) { local int i, s, DesiredTeam; local pawn APlayer, P; local teaminfo SmallestTeam; if ( bRatedGame && (Other.PlayerReplicationInfo.Team != 255) ) return false; if ( Other.PlayerReplicationInfo.Team != 255 ) { ClearOrders(Other); Teams[Other.PlayerReplicationInfo.Team].Size--; } for( i=0; i Teams[i].Size) ) { s = i; SmallestTeam = Teams[i]; } if ( bPlayersBalanceTeams ) { if ( NumBots == 1 ) { // join bot's team, because he will leave for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('Bot') && !P.IsA('RemoteBot') ) break; if ( (P != None) && (P.PlayerReplicationInfo != None) && (Teams[P.PlayerReplicationInfo.Team].Size == SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = P.PlayerReplicationInfo.Team; } else if ( (NewTeam >= MaxTeams) || (Teams[NewTeam].Size > SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = 255; } } else if ( (NewTeam >= MaxTeams) || (Teams[NewTeam].Size > SmallestTeam.Size) ) { Other.PlayerReplicationInfo.Team = 255; NewTeam = 255; } } if ( (NewTeam == 255) || (NewTeam >= MaxTeams) ) NewTeam = s; if ( Other.IsA('Spectator') ) { Other.PlayerReplicationInfo.Team = 255; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); return true; } if ( Other.IsA('Commander') ) { Other.PlayerReplicationInfo.Team = NewTeam; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); return true; } if ( (Other.PlayerReplicationInfo.Team == NewTeam) && bNoTeamChanges ) return false; if ( Other.IsA('TournamentPlayer') ) TournamentPlayer(Other).StartSpot = None; if (Teams[NewTeam].Size < MaxTeamSize) { AddToTeam(NewTeam, Other); return true; } if ( (SmallestTeam != None) && (SmallestTeam.Size < MaxTeamSize) ) { AddToTeam(s, Other); return true; } return false; } //Shouldn't matter - dont think it is actually called in teamgames //voided for remoteBots anyway though function SetAttractionStateFor(Bot aBot) { if ( !aBot.IsA('RemoteBot') ) { if ( aBot.Enemy != None ) { if ( !aBot.IsInState('FallBack') ) { aBot.bNoClearSpecial = true; aBot.TweenToRunning(0.1); aBot.GotoState('FallBack','SpecialNavig'); } } else if ( !aBot.IsInState('Roaming') ) { aBot.bNoClearSpecial = true; aBot.TweenToRunning(0.1); aBot.GotoState('Roaming', 'SpecialNavig'); } } } function ClearOrders(Pawn Leaving) { local Pawn P; for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('Bot') && !P.IsA('RemoteBot') && (Bot(P).OrderObject == Leaving) ) Bot(P).SetOrders('Freelance', None); } function RemoteBot AddRemoteBot(BotConnection theConnection, string clientName, int teamNum) { local RemoteBot NewBot; local NavigationPoint StartSpot, OldStartSpot; local int DesiredTeam, i, MinSize; NewBot = SpawnRemoteBot(StartSpot, theConnection); if ( NewBot == None ) { log("Failed to spawn remote bot"); return none; } NewBot.PlayerReplicationInfo.Team = teamNum; if ( clientName != "" ) NewBot.PlayerReplicationInfo.Team = teamNum; if ( bBalanceTeams && !bRatedGame ) { MinSize = Teams[0].Size; DesiredTeam = 0; for ( i=1; i= MaxTeams ) NextBotTeam = 0; } if ( bSpawnInTeamArea ) { OldStartSpot = StartSpot; StartSpot = FindPlayerStart(NewBot,255); if ( StartSpot != None ) { NewBot.SetLocation(StartSpot.Location); NewBot.SetRotation(StartSpot.Rotation); NewBot.ViewRotation = StartSpot.Rotation; NewBot.SetRotation(NewBot.Rotation); StartSpot.PlayTeleportEffect( NewBot, true ); } else StartSpot = OldStartSpot; } StartSpot.PlayTeleportEffect(NewBot, true); // Log it. if (LocalLog != None) { LocalLog.LogPlayerConnect(NewBot); LocalLog.FlushLog(); } if (WorldLog != None) { WorldLog.LogPlayerConnect(NewBot); WorldLog.FlushLog(); } NumRemoteBots++; return NewBot; } function bool ForceAddBot() { // add bot during gameplay if ( Level.NetMode != NM_Standalone ) MinPlayers = Max(MinPlayers+1, NumPlayers + NumRemoteBots + NumBots + 1); AddBot(); } function bool OneOnOne() { return ( NumPlayers + NumBots + NumRemoteBots == 2 ); } function bool NeedPlayers() { return (!bGameEnded && (NumPlayers + NumBots + NumRemoteBots < MinPlayers)); } function bool TooManyBots() { return (NumBots + NumPlayers + NumRemoteBots > MinPlayers); } function RemoteBot SpawnRemoteBot(out NavigationPoint StartSpot, BotConnection theConnection) { local RemoteBot NewBot; local int BotN; local Pawn P; BotN = RemoteBotConfig.ChooseBotInfo(); // Find a start spot. StartSpot = FindPlayerStart(None, 255); if( StartSpot == None ) { log("Could not find starting spot for RemoteBot"); return None; } // Try to spawn the bot. NewBot = Spawn(RemoteBotConfig.CHGetBotClass(BotN),,,StartSpot.Location,StartSpot.Rotation); if ( NewBot == None ) log("Couldn't spawn player at "$StartSpot); if ( NewBot != None ) { //hook up connection to socket NewBot.myConnection = theConnection; NewBot.as = theConnection.as; NewBot.ae = theConnection.ae; NewBot.ib = theConnection.ib; // Set the player's ID. NewBot.PlayerReplicationInfo.PlayerID = CurrentID++; NewBot.PlayerReplicationInfo.Team = RemoteBotConfig.GetBotTeam(BotN); RemoteBotConfig.CHIndividualize(NewBot, BotN); NewBot.ViewRotation = StartSpot.Rotation; AddDefaultInventory( NewBot ); if ( bRequireReady && (CountDown > 0) ) { NewBot.GotoState('Dying', 'WaitingForStart'); } NewBot.AirControl = AirControl; if ( (Level.NetMode != NM_Standalone) && (bNetReady || bRequireReady) ) { // replicate skins for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo != None) && P.PlayerReplicationInfo.bWaitingPlayer && P.IsA('PlayerPawn') ) { if ( NewBot.bIsMultiSkinned ) PlayerPawn(P).ClientReplicateSkins(NewBot.MultiSkins[0], NewBot.MultiSkins[1], NewBot.MultiSkins[2], NewBot.MultiSkins[3]); else PlayerPawn(P).ClientReplicateSkins(NewBot.Skin); } } } return NewBot; } n . ?,0?,@BA\.~  A?,BA\d,\h'\j(\o%\ v3000 _~W#- |J\T-~ \y 6i [?,?,d?,?,dHCC  p  p m f p  m e m Z m G m E m  m H m Z m i m H m ` p W m w iM RQ m b m l m  p Z cl iZ RL iF fz m c m F m k m K m[ lu p D cS jf m j l~ iN m m iE iK cr m H m I i^ jH lk m @ m [ l_ m ` m v j| m X m f iQ iU ls m  ly m  p l m t m b m { l` lC j} mS m y mX m A lZ m f cW Rk iK lx i` m u kY m J cd l[ m h kZ jq i lh mP mQ K; c~ k{ cd k\ kV lj jh m I it le ji l^ js k} H m N l} m e ka iC m K kS ke Kb jg iR io kv lp fS k} dm jg iR kB bO mf m J iN m } m x m y lA m m dm bT jC mN cN lo fV iN iR m x H{ kB jg H' kG kj iO jc i] kp j^ jx iT fT jl is H' lT jE k@ lC k\ kd j^ ie ku H H0 i\ k@ ik HR m p Hg Hy jY jm b` H l@ kB H[ Ha lZ kV fD lE kc jm l] fD iz Kd lf Hi b] m D iB HJ b\ iR H$ iP jn HQ H9 lb kX b_ kc b^ m U HY j[ dx iM jO izI m s kb lm[ jw H| k| iy m r kS li m A i}W H] H0 m q kh k[ jq K kb ll k H H# HC HW HJ p v m G m~ Hn HX iT iS iQ Hn H\ Hu H] m q b4 Hyn iI m[ m B H" H' Kd K m t ki j m a Ht kZ HG jU kj HF m d iG H{ f{ cQ ih cE jl jF kd m F cx p C k~ HH i@ m[ m x jt kd H9 H' H H{ Hv l] HT H_ ky H6 Hl ks ip be kz Hd H0 H{9 H^ kU bx HD Ha kT jQ Hz Hy HS Hr b< kO H} HV k H{ HF kA H{ iU HB Hc ck Hf HX kp HF m r iW H+ dyi bF jD H^ cL Hq H}y HW ko H HL HN Hc it H7 H} js HR bE iT H_ m A H_ k| kB iS H kq H9 jx kq m h m g HE m V m i Ht H\ m k HF HZ KY H! Hu Hx kA j aw Hh Hn HL HQ Hw H| H{Rj \ Hn H" HI b< ig cn p u HG H@ Hq m n m m HE m l m j kl H8" H{ H@ HP HJh { Hnh z h w h u HU HT HR HZ iT kh H` Hf HI HN HJ Hg Hcj y HE dyc k jo Ht Ho jp HK Hm Hl Ht kJ dz lM H~ H0 lR H{ HP HR jp l y l x p vj (v kn Hs H] HM HS Hgh Y m o HX H X H 9 H| HX HY HS HJ Hc HF HO H8X H8M HH HX HM Hc HO H0 H` Hf H0 p w m } a su T w `S ns zu FpIRI`InI|^cJ]Cm\k  p u }\ I\F WS es qg }G3J\G Q^G  _ C l4t zIHt Vt dt r S @QILIZv  h\` utt Bv  Pv  ]av  j s wt C!t QI_v  m^` zOoG^k  v\a Co  PG\o  jGwt E^F So  a_ mag  {\s  HGv  Tg  ag  nG {t Gs UkIcd  q ~@ Ls ZP  ju w^a DkGQ Y _w  lY yiM.FI SYh&`[@-H\^Hv@ fj@ saI@I Nu [v  hR tP  B_  OI\k_  j_  wKa DOa PtR \Ij!R xI F~  SNa _Ma k4I w m D n  QX@ ^ S ku x s E u Ro  ^a kt@ yOP  FU SQo  a~u nI {o  Ht Uo cAu rK^M^MkX [N^hI vo  CTo  Po  ]O^iv  w\} Dkd Rh  `I mh  zmI G^H  Tah  ab nXB |s IIUv cS qO ~I L\B Y^E g\_ttB Bv  OO [,m iS vG C(hP"v  _t kO ys G#m  SGu _O lGI zj  GI Tao  avs nt  |js Ijo  W^J  dvo  qR ~Xr  L\N YO`go  uR Bo  P4R ]!o  k\P  xM DZ  PR ]t  kxPxQt  FYW  SK`_N`m` {L HM`Wm  eto  rPo  Mtr  Zko  g Z  s|P@\E NJ ZG ggo  s~S Gs LGS Xa eyK sQd  AQa NAS \Qe  ic  uGo  Btf  Oz  \d  iX vyW De  RvJ ^XC j\Aw~s Ef  Ra _P  mo  zjJ GNv SfaAs oez  |ko I,Z  We  dd  pS }s Ju WtC dSo  qd  }Y|  J Z  Wo  d!f  po  }eJ JGWee4esK  Ag  NR ZM@jhK  RMVV_yM uu B Oa  \sK  i\H  v`CZ@ c^_p^B ~a  L4a  Yef^} tD  B@ N @ [w hy[  vX  C,X Pq \n j X xX~  Er R@ `t~  m[  zY GeUI  ca  pm  }m  Im  UC at  nO {p  Hm  Tm  `P lL  y R F~ TW  bL  ot |o  J] Vw  dR q D r  Lu  Y K f w  sV  @b  Mc  Zg  gL  su  @x M,K Zt  gu t!g  Bw  Nb  [Z  htg  uXD AP Mc  \t ir  wT Do  Q^I  ^yv kk^  yeo  Fs Rar  _Qb  lQc  ym  Fpu  R^  _s{  kb xQ ES SY}  `zp  m  yR EZw  Som  `r  l"m  y t  FS SZR `J  n| {FQIb ZUgm  udL  Am  N\O  Z\M  g^X  ts Apm  Nm  ZQ fu  t Z8AM_ y"}FNHCg Q\L  _[ lp  za F@ TAv  a @_msFLj  Z^Agy  uN]Bi  Pc ]ZG k[  y^F F{ Sf aN_ osE |[  Isc VG d q)rK  [\X  h [  uZ[  Bq| Ov  \W  hH~um  sM]!f M~v  [m  g!W  stW  @C  MHZI  hMt G B[  Ptf ]^L  kK_ w{ D[  PV  ]e  iK]vI  DC  P,D ]u  jd wD  F\ SH `tA mO]z~ HM  UV b u  oM  { v  HO_ U S b\ o g |V I  Uv  bg nR  z~  GW  Sn  `G m[~  z~ GL  Sc  `r  mG yTL  Gd  TTr  `XA lI  y,S EG RFQ  `f mN[  z[  G_Tsf b Fvpb fr  sm  @DLsg ZjI ha ug Az O_\\F j` w@ Ef R8@ ` wam8R N8A\QI j G_sa Rr  ^W  kTsw8Dj b x8[  Der  P6B  \@ iR vADX@RDRc ` E&lf RQ _gF m ^l z[  fM rP  @rv  MJZ[  x`sDyM wc5DDyL  GA SA`And  |R I'd  WzI d@ qAj~zB hz v!|  Cg  P$L  ]c  iB vk Cd  Pa ]d  it vW C Pt|  ]tejb xc EU Rr _d l s {(]G!eVh d[ rG r LO Ya  e|  re Mz Zmh gdc u|  AeNSF \f ih v D YP yRiSG { J*HtD r tl~ g]jSz  GnLT[~ `[M n[g {[N H[c  U[O b[o  o[w  |^I gPg[s w YE[P ^jc  k )UxqJM 'mW|"D|"fL@_H@G_gkY FkZ Sjf  `t~mgz  k plxvw  dBxqAZGi^qtp|"dBxFK'I~KmGgG tv3Az  tPE&@L@:fK\`T^(|z  d Y-qjg  ^ YRk ^`} `p]j  MW  Z d@g l9gK0Y` l%y 7J^U  ho  uKR]A {N^K9H l vXtz  L T?XO W T@d u@d \kdk[ O|wa\F }yRKKCB ]J!_vI @vg  Mz  Zk\ fgKs'F~ U{D nm%dYllFvE~z  { m.Hz  v y_CKi bz  Kv/Wz  FCFSIu Yf  NO [z  iPLuK]{Az  |K#KIAZWTykK-fd^qPJ aZZXCtz  w9DD]cHYJfu_ DuE QuF^KJNlz  zKi/Fz  uK:Az  {PG&z  UK.E a yHf dYnz  G[  THafHoiMXhvA ^[  kY!xN'WYNmpz  ][  jv vHDSRNCqz  tJAc_Y  }L IFWOv_ TE aN0KnFysFGA f[  sH@fHN[  mU  yNRtEDyN9lGAsz  AR NH  \E iC"wb-TXAM"_f A gIOC Xg fNkt)M"_c A)O"O v3q z  dB qN )_\L ^hMF[  T)I&a MgG V3n,gIa){CjKkm)`"XN#Kz @jE )f"o N-fQ  6fw  W}] ,yKZ !z  e K$/r  [Ma s)Fn ;_ L +0k dNG NJNU ,z  c Ni/o .z  ^ N:j 0z  d N$/p 2z  _ N.E k :0p :_&M 4z  s C:"0@ :X!p cQ <z  t r!@ >R  a Zn CR  M M'[Z Mmu Az  b oo Ez  N g!Z P-{ MZh Gz  B K| O Kv \ Jj MI Nk  g S_t MRmS Rv  @ MCB M nO Uz  n Uv z N!H XY  i XL u FC s_b Mkp \z  [ V}"h ^z  e _Rr Zz  D cz  Q Mi ] cx  F P!S az  t U_A |` af  ~ aO K WFY lP  _ M]{l tg M#KF A Q qW ^ M0Yk BFD qZJ pU  d M-np sF^ @ } yw J tz  V z{c Io^ |_  M ]Z ~L y cRE MJNW z  e Mi/q z  ` M:l z  f M$/r z  a M9nm ]  [ z  g E]t SwQ M.E H {PM FP] z  m GPz K  J J V I  d +q ggO w v y  B O'_O O[n z  I `V }Nd w r y  ~ OkK z  v NC LsQ QsD z  w nvC O.E y H  ~ hK z  j z  w Z2C DPu OHE A M B Z z  h } u f#C OJNf z  t Oi/@ z  o O:{ z  u O$/A z  p O0Y| s9U t*N U  x OkD !o U L XZ xy z  W ^  d O9nq Z  _ z  l q 4my ,q 4Uf O-j{ NCB e "/g q 4|V z R P\` q 4nQ| ORIj q 4js FRS] 'yp q 4pi FStY  QeM q 4sr DWme q 4rR dBD )HAF DUlG )Xs )c+Q ~| '"Z m  | n  I `&U )t&{ z  a Rtm q 4~/aNi _ q 4OHaIWz  `q 4e)mY.R,aT@z Tn-bq 4O Oq 4Z^,[Mx aTEq 4iYz  B)0Nz  kf  xnjEZHo q 4awMq 4JX q 4Xb,QezU  _V  l\px)"0hO XN]{fNq 4DaOq 4^eq 4{C q 4Z~(_ XU  eV  r|@~N@~Lu~K[sq 4^N}Zl{RFocXMA{u"|]f^_uD(q 4ry(E kKq 4Ax(i y (noG (W=v (Fs yGA [FriendlyBotAPI.FriendlyBotCTF] bNoTeamChanges=False FriendlyFireScale=0.000000 MaxTeams=2 GoalTeamScore=4.000000 MaxTeamSize=16 FragLimit=0 TimeLimit=0 bMultiWeaponStay=True bForceRespawn=False bUseTranslocator=False MaxCommanders=0 bNoMonsters=False bHumansOnly=True bCoopWeaponMode=False bClassicDeathMessages=False bDumbDown=True [Botpack.TeamGamePlus] bBalanceTeams=False bPlayersBalanceTeams=False [Botpack.DeathMatchPlus] MinPlayers=0 AirControl=0.350000 bChangeLevels=False bHardCoreMode=False bMegaSpeed=False bAltScoring=False bTournament=False NetWait=2 RestartWait=15 InitialBots=0 [Engine.GameInfo] bMuteSpectators=False bNoCheating=True bAllowFOV=True bExternalBatcher=False AutoAim=0.930000 GameSpeed=1.000000 MaxSpectators=2 AdminPassword= GamePassword= MaxPlayers=16 IPPolicies[0]=ACCEPT,* IPPolicies[1]= IPPolicies[2]= IPPolicies[3]= IPPolicies[4]= IPPolicies[5]= IPPolicies[6]= IPPolicies[7]= IPPolicies[8]= IPPolicies[9]= IPPolicies[10]= IPPolicies[11]= IPPolicies[12]= IPPolicies[13]= IPPolicies[14]= IPPolicies[15]= IPPolicies[16]= IPPolicies[17]= IPPolicies[18]= IPPolicies[19]= IPPolicies[20]= IPPolicies[21]= IPPolicies[22]= IPPolicies[23]= IPPolicies[24]= IPPolicies[25]= IPPolicies[26]= IPPolicies[27]= IPPolicies[28]= IPPolicies[29]= IPPolicies[30]= IPPolicies[31]= IPPolicies[32]= IPPolicies[33]= IPPolicies[34]= IPPolicies[35]= IPPolicies[36]= IPPolicies[37]= IPPolicies[38]= IPPolicies[39]= IPPolicies[40]= IPPolicies[41]= IPPolicies[42]= IPPolicies[43]= IPPolicies[44]= IPPolicies[45]= IPPolicies[46]= IPPolicies[47]= IPPolicies[48]= IPPolicies[49]= ServerLogName=server.log bLocalLog=True bWorldLog=False bBatchLocal=False DemoBuild=0 DemoHasTuts=0 bLowGore=True bVeryLowGore=True [FriendlyBotAPI.FriendlyBotDomination] bDumbDown=True bNoTeamChanges=False FriendlyFireScale=0.000000 MaxTeams=2 GoalTeamScore=100.000000 MaxTeamSize=16 FragLimit=30 TimeLimit=0 bMultiWeaponStay=True bForceRespawn=False bUseTranslocator=True MaxCommanders=0 bNoMonsters=True bHumansOnly=False bCoopWeaponMode=False bClassicDeathMessages=False [Public] Object=(Name=FriendlyBotAPI.FriendlyBotCTF,Class=Class,MetaClass=Botpack.TournamentGameInfo) Object=(Name=FriendlyBotAPI.FriendlyBotDomination,Class=Class,MetaClass=Botpack.TournamentGameInfo) *E@='<xCCO>YJNone BotClasses DeathMessageDeathsFriendlyBotAPICoreEngine InternalTimeBotpackColorSystem otherstring TauntString OtherSound TauntSoundVClampUClampUSizeUBitsVSizeMipZeroPaletteVBits MaxColorDeathModifierBotAPI OtherAbbrev DrawBigNum spreenoteReceiveLocalizedMessageMesh OrderSound OrderStringClientReceive bHasComp CompFormatDieUWHit2 breathagain GaspSounddrownUWHit1 LandGruntGibbed HitSound4 HitSound3 HitSound1 SetMultiSkin VoiceTypeSpawnGibbedCarcass HitSound2MajorDeathMessage SpawnCarcassUserWAVbMaskedHeadLossMessage NameSoundAckTimeWaistjoint1 AckString AckSoundBodyjoint2HeadLODSetFire ReplaceWith BubbleWand GetStringWeapongoowand NameTime AddMutatorFire2 OrderAbbrev InitGameLoginPostBeginPlayBroadcastLocalizedMessageExplodeMessage LeftKneeLeftHip LeftFoot HidePlayerScoreBoardType LeftElbow PlayFiringKilled LeftShoulderDead9 RightHand RightElbowProjectileFireBreath3PickupMessageUseAmmoSelect PlayRecoilRightShoulder RightFoot RightKneeParseKillMessageSuicideMessage LeftHand RightHipAllLocalizedMessageClientAltFirePlayAltFiring GameNameNeckExplode AltFiringWalkDrownedMessageDead10GunHitLFootLKneeLHipRFootRKneeRHipLHandLElbow LShoulderRHand MenuName SpecialFireIconPlayerViewScalePlayerViewMeshPickupViewMeshRElbow RShoulderDeathMessageClass BotMenuTypeDownFighterRestartBeard Victory1 LMustache RMustache ItemNameNoseHatBubblesBioAmmoFemaleSuicideMessageMaleSuicideMessageMortarMessage DrawWeapons DrawStatus ShockCore TrainingDM NotifySpree ThighPadsbExtraEffectsSpawnedChat2 EndSpreeDead11DodgeF StatusBeltHUDType StatusDoll UT_JumpbootsUT_ShieldBelt DrawDigitChat1DodgeBDead8DodgeLDodgeRDead9BBackRun FFireString FFireSoundStrafeR bLowGore bVeryLowGore StillSmFrStrafeL EffectSound1 UnrealShareSwimSmTournamentPlayerFlipThrustDead6RunSmAimDnSmBurnedMessage FallMessageAimUpLgAimDnLgCorrodedMessageHackedMessage DeathTermBotConfigTypeWaveLookLWaveLAimUpSmTreadSmThirdPersonMesh StatusIconRunSmFrRunLgFrDead4LookBotTaunt1 DrawAmmoBreath1 Breath1L Breath2L CockGunLTurnSm StillLgFrUWindowTurnLgLeftHitDead3 SelectSoundDrawFragCount LandSmFr LandLgFr RightHitDead2Dead1SwimLgCockGun TacticalMoveHeadHit StillFrRpSelectionMeshTreadLg WalkSmFr DuckWlkSBreath2Dead5 JumpLgFrRunLg DuckWlkL JumpSmFrStillWalkSmDead7WalkLg SpawnEffects WalkLgFrRun CockingSound BeginState ShockRifleGetSelectedIndex SniperRifleAutoSwitchPriorityPlayerViewOffsetLoadCurrentValuesSetSelectedIndex ImpactSound ProcessTouchIdle SetValueSetText ChargingAltProjectileClass AltFireSoundCreatedFlying PickupSoundInventoryGroup AddString ChildMessage DrawColorCheckReplacementAltFireShoot1FriendlyFemale1FriendlyFemale1BotFriendlyRemoteFemale1BotFRemoteUTBotConfigClientChallengeDominationHUDNewFRemoteUTBotConfigSClientChallengeHUDNewFriendlyScoreBoardDomFriendlyBotDominationFirstBloodMessageNewKillingSpreeMessageNewFriendlyVoiceMaleOne FFireAbbrevShoot2FriendlyScoreBoardCTFMultiKillMessageNewFriendlyWeaponMutFriendlyBotCTFFriendlyRemoteBotInfo magicexploFriendlyRemoteMale1Bot bubbleExploFriendlyMale1VictimMessageNewFriendlyMale1Bot magicRingFriendlyChallengeBotInfoKillerMessageNew EndSpreeNote EndSelfSpreeEndFemaleSpreeFire1MultiKillStringTripleKillStringDoubleKillStringYouWereKilledByUltraKillStringMonsterKillStringFirstBloodString KilledStringboltendArena ShootloopVectorWalkingLoaded bubbleRingDeathMessageNewShoot3 boltloop hitdamageUMenu Projectile ExploSound UnLoadingStill2 TauntAbbrevWeaponDescriptionAmmo boltstart YouKilled BulletBox SkeletalMeshSkinTeamNum FaceName RedColorbIsConsoleMessage PlayerOwner Rotation SkinActor bIsAnArmorClipY TextBufferPortal DamageType bAdjustSkill bRandomOrderInv Palette4PendingCharge ArmorAmountObjectPackage PawnOwner Palette1ValueHUD NewPlayer bChecked SkillTauntsbSuperRelevant NextMutatorUMenuLabelControl Palette18 Palette22CollisionRadius GameInfo TauntLabel NumBotsEdit Palette5 LevelInfobAltWarnTarget BaseMutatorDynamicLoadObject FiringSpeed bSpecialIconClassProperty NamePropertyObjectPropertySkinsCarcassPlayerReplicationInfo Palette3ChallengeBotInfoCurAbs InventoryCanvasLevelFloatProperty BotConfig HitActorbCoopWeaponModeSkills PawnList bDropDetail TimeSecondsOptionalObject RelatedPRI_1OwnerStartTournamentWeapon nextPawnYUMenuBotConfigBasespeedmyHUDTarget InstigatorGameScore BoolProperty ChallengeHUDCTFGamePendingWeaponEnemy PlayerName AmmoTypeMomentumTransferUMenuBotmatchClientWindow bPointingM BaseComboBotmatchParentAutoAdjustCheck Velocity bIsFemale ShockProjUnrealCTFScoreboard GoldColor HitNormalStructDamage HitLocation SpawnClass RandomCheckMutatorKillerP PurpleColor WeaponScale Function HUDScaleOpacity ScoreTimePlayer MyDamageTypeScaleState AmmoAmountDeathMatchPlus StrPropertyStructProperty TeamGamePlus ShockExplobBalanceTeams RelatedPRI_2FirstBloodMessage bDumbDownTournamentGameInfoChallengeCTFHUD LastKillTimeUT_RingExplosionNum ReturnValue TMale1BotMultiKillMessageKillingSpreeMessageKillerMessagePlusDominationScoreboardDeathMessagePlusCriticalEventPlusChallengeDominationHUD VoiceMaleOneVictimMessageTMale1 FireAdjustCriticalEventLowPlus MultiLevel bAutoTaunt Palette10bNovice Palette12 bFirstBlood NextTaunt bEndOverTime HUDWeapons TutIconBlinkbHideAllWeapons bHideStatus BaseColor HUDColorSolidHUDColorHitPosHitTimeUpScalebMinus StatScale ChestAmount ThighAmountH1H2 DamageTime bChestArmor bShieldbelt bThighArmor bJumpBoots bHasDoll BotOwnerTPOwnerDoll DollBeltWhiten WeaponSlotBaseYBaseXWeapXWeapY AmmoScale WeaponOffset WeapScaleWeaponXTexXTexYbCanClientFireEndSpreeNoteTrailerBalanceTeamsCheckDumbDownCheck IntPropertyRemoteBotInfo VizServerRemoteTMale1BotRemoteUTBotConfigClientBotDomination BotServerBotCTF theVizServer theBotServerbServerLoadedRemoteBotConfig BytePropertyMaxAmmojGWCurXSkillClipX ut_biorifleCurY Palette9 ScriptText TranslocatoriUWindowEditControl SkinNameStep ClientClassUWindowCheckboxUWindowScrollingDialogClientUWindowComboControlFixedAreaClassBIconsRBest MinPlayers GameClass Domination StatusScaleManNew ManNewBeltFriendlySkins RobeBlueRobeRedwizActorOther DifficultybHighDetailModeXAltProjectileSpeed MutatorClass WhiteColorDamageScalingSoundDampeningSetPos DrawIconPawnHealth LocationD VoicePack bIsPlayer HurtRadius wiz103Anims LocalMessagePlayOwnedSound wiz103Tex0FriendlyMaleSoundsouch RobeBlueFem Palette8 RobeRedFemwizFemStyleOptionsSoundTextureErrorPhysicsSwitchConsoleClass Palette7 Palette16 Palette13 BestArmor wizFemAnims wizFemTex0 UseBubbleBubbleWandMesh PlayerPawn AnimationBubbleWandAnimsWandTexWand BlowBubblesgurgleUseGoomagic goowandMesh goowandAnims goowandTex0 WizVoicemoofHUDElements1NewBubbleTex_a006ZmZRIFFREWAVEfmt "VDdata.EF_| .::>Kg&,+/AKRM6#cuR?)5?w\: Ho'=O_[LEJP]faN=D]{tecm9oxT01Pn]7#,&eB0'&>]k;! 0@GA1#%AdQ \j5W  %Z'%N#"%*;.00A1~/ % ÊT񟝣0EV NU;!)-/0061-cP_i :* +? !f)-/#1- c ׮¾ˠ} L/ H',/11, VׯXon\V#+..(-E3hԱlxY B *@"+.+-S("6 2 zNMn"M*.i1203R3332W/'a!S'4+)81 zF;䜄*F%@+.0-%*4 &E+_-.+;"#qʡ*ɟ:;S> 1+'' c,"%5%!$ BޑޡҒM N((Jj'/,.//)* gT #A}G6  ',/1$0y%!~i.>D J(q'I-0[2/;%Z͓V*:z2~2 ;#*/L1G20,%gS V(9,.)/P//+q CFa[R."R)x-8.&We$),-d.k.u.&E`ӣV~%#ˎ+'{&  <; &Q"k&$pwmqZ'/8 2Cs#)U-.+!A!˶'tzBˤԫKJݸXې #+F, yms٘MtN@P'-+E#;3ԱB3- !U5Y1$z"C+01~/`*2$s")O.*0103%+ɾX/-$d#*7/U-#""$[*-?/Q0/:1U*ĨdG$0 \ZT7c',<,u}Ы*y \T,F$+_//:"#?ͷͿ^7>rBרn7D{SAjrF?Qa_ b m p p!  #,*.//m1u2(30f4j-B4F!  8Qx #' Eȷmo K vhP @Y. ozy\3ԍr'u]t2- p ;n ߘUM]M ,_l9+Cn1YY  (l8C V 9D%a)-+=,+# d6bLp#M: N)=*. 52xxXͨٱZ9 R  .}HyME M ,6iA[0 L [b z - Uxp&bm(>V}{kq aNQ`p o|CI"ěOE< _72R_ I~Pխ:َ ^7LK {,X.B qI0` p; ~  vi)lQ' $ u0J n^r:J`jf  ~SI$$mA%e! Jp 8$,lq [H 8 gn\5  J  %L z@ 4!/)7 @ 51Md>'TD ! ~eA-S g he |VkN^$Yy0  ^ bR@M7P=81G :>7zֲ!ń"؀>0 ,c " 6 ?6{I0 +8D' D n7VKF%3Nw@D>r3zH\=C'T<@?w1s j !42V2. Cq{Z%Qro5o9 U ?SfG1+t˜]w5w ~?`  FSlޅ;n  kU\ iPHlH$6Gps11(k9y.sF%' 6%?hGuErKu>$'6 J q n l\_  ^% & 2^o !)jY  6 E;|^J@XVaB{T#6}PgS*I/v2J(~f~/ &HmG6x s7%yX=5iu ? 2 D2feѭ )m Wv%ku&R~4a,^sd $ fyfU?OH9T:Ns[T[l&ez{I3)exb2)E2Y99QT+8FlQ1JMXYVtYD blGLqQp'VO% } m k8ݓ9 = 3-}RY _ QT",h"f ? I~ [C)Rs^rGi o 2 .@}[4u:v}!9DNg';.@RByhO@(@X ~j N20$]k &[+C~܍Vpy , K ,GFdws)^t{u c  ygs]~o[fs  } xTjhy]]0?D J%7ZT w\(}iIS}/'+!j= 'EJ^LVTGAX b { S @dW3E}5nqDIK . 5 5ur%i]s@`G 24QbmzuB!*Gi9j:G=P$T}hik2iWr# sEbk>rW0Wm6~,bR(Po~ c e OS%4Vkj k%?jmHRF_i[g{3$?_)Hh<7@`<VR)  m mJKu0 6h N2'Me4 u9 tp~#@5 9qr MEiW+OG y,ia- AHVL%PNO}v_A[sv(@,e{_8Q<\ }gqSSp1B_ 5JTM<XMw v;/UYNYi\.89T)M~(FLCG9Wf(/I1_%cX!kQ*8&?e'@ q2f3mA&N9[wT;Z}F36$ucV4@^=\_` d9 Xaik2cF"Sj|_9fZ(lxJ.WpZk-rhoAx-FlEt.[)91 g6kGDW)(Qk"y["P1rF)Ly ndB8lF< 0+FV1N[pG 0pw$vRxL[7 g }klgI 4C,MQUQbv5VSy(\ZPq4{*)#4Va$H(\% ![ivz1["66s6!0 h9@'?6O<:laq$zy@2C+<@c6wRbq|r>C}[wY.e I df{T^!+AN(Qry`3R'pOGy6]_0B`2>2?YGw1];*u ZZQ,bo>]xTUV%I,F Vi@Df]w u)q,\sKRmX^]Z~)@o0^Fa1%gqm?h~Ql Dc%gdKpG:m+ndAHKk4d%q9jxWjyRSdiF3] Qq\(6\Yk!wE "YFm"o^a~Aa#o_@ j19}<*]K 3tl9=S1g/T&_ms"

.sWT(|61 n-~97em-e~@?;p3n X|dVV-EI2o{[7VQunc^gu(_h{Z0[ .RsP@+PN])+s4f#<qya|`hN3  F5D}X5aoojhmk_9rhuj5=&ufAtv _{#U>fad2t;;j >i@%3]%|#=KG4?nb hq/UxwjHZcygx9I&(%[ p.pfa4JP+s:AFNRQ2)+p'WNJkgsl{q~[%oF /[rX'K 1y\BhFll hK!_O>}WnidQ@d{ NyQ.}~ NWB2"#+' 1\Udp([Ra[v*)B5aP;O*7uJ'%]JPRAq |m %X{~U>RSf+!@SH#lh2Tu u;z0~KLL$#]g_I&HCbs:y(GUVuI!3q1a6:D04O;k%l&cZVTZk7MFz@*1I^XMa,FH. 9 9v-&"jk2,Y{>' $cke8irQ#g4f%]kQ DJ!0xRKR SKR 4_mu=\qxjYJ3}<+rJx[.F_QWm g^PwbB6Xa@xcV:*8il-Y$[7\r7u-nV)S!3_=,]_Z= |niaK;O6KQOPUN4(U_r0M(CL_X yzIY 2t}K< CoYB% FYNJilBr[Uc} I[9_z}pbO4 $HsMz?[y h"pqh# slY0 +6% B`u =gz1hw8[];=r&b7?FSu1|Hyj)}y|~\LGK[h|jUM\7V\YWZ_kh Fzd$Sp:->?=NhZ6@RIFF8]WAVEfmt L>data]@0 @  `  ` h`@ `P@`@ @@`0` @pp `x80@0`0@ @@`@H`  h` @ @  @@H@@`0hX@@ @P`8Px0`xP@0  `@@0p P@@`@  @@P@ `8p8@@  @@ 0 X @  @@phX` `h@8 @@0@@@@``0 `` ``@@X@ @@P@@pp@0@h@P@ @  0@@@8pxP     @`@ @x8  @@@@`h`p8`  `P ` h`p P@@  ` 0( 0``   p@` @ @ @`H@``@   @@p@@@H@@   @@@`px@@x@@ @@  @@@@ ` @`0  `@  xP@``@`@  @` `p  @ @ @ @@ 8@@ @@@`@@@  @ `@ @`` ЀЀހ@@ @ H P @ 0 `P@@ @@  ȀЀ܀ '   @  @@ @0 `X    Ҁ ') @   @ @ @@@ `@ p @〴܀0 1'   `@ @ @@ 0 P p Ѐހ@`++ @@@ 0 ` @@@ H   Ҁ€؀%1   @ @@@ @  ` @ڀ΀`!7)  @@  @@   p  @  `Ѐ0 1;  ܀ ހ @ ` @@@ @    @@€ʀ1=!p@  ؀ހ@`@ @ @@@ @ @  !ހ̀Ҁ `5/#P @ր`ހ  @  @@@@ րĀր΀ `9) )`  ր܀ހ`   @  `P 퀴ڀ؀  )1' ހր ހ@ @ `@@@@ @ @   P̀̀܀@/ !  ΀ ր@ @@@ @    €؀܀@)  ̀ހր@   @   @  @Ā܀܀@ '@܀ʀ @؀    @@  ހ'#! ܀Āހ ހր     @ `@@ ܀ '@  ؀ހ@@Ѐ  @@    〴΀# ꀼȀ@ ހ̀   @  ܀@ @  ހҀ`#% ހ̀  @؀Ȁ@  @  ܀ Ѐր܀ !%'+#؀΀Ҁʀ ` ڀ@ ܀ʀր@!+! @%ĀĀڀ̀    ` ހ0  Ԁƀ܀܀@/!)+)!Āƀ؀̀    ր؀ @@@#!Ȁ̀ހ؀)?+!11#/'쀼 ҀĀЀ   Ѐր p %' !Ԁ ;C-)51!!+ -% ̀ ؀Āƀ @@!@@Ԁ !)@؀+G37K?3'@% ڀڠԀȀ   @@ /3! 䀤ĀƀЀڀ )-'3GC3+# %-܀ʀ ڀ@ @!  )ڀȀЀ܀Ѐ1)/G?+/1 '1‼€ހ܀؀   %3' @܀܀ހހҀ#=#-;+)!@@53΀؀ʀȀ   `!1- @ €Ѐ܀ ؀7/#-1!#@1=#̀΀Ȁ@ '`39# @@ƀր 1!;S5@/=%؀ĀԀ@ր %)+5!  @3)OC /G1@΀Ā ڀȀ@=;'%/?)1+ԀĀ ) 9O?# )CC†̀Ҁ`΀ƀ؀@ 5WS?- )3ꀤʀ@%S_=1/%)``+;#ʀ΀܀ހ܀€ހ COG9#- ΀ڀ p CO9%'3-# '?C䀨ƀ΀ /CC5% #))@܀Ā  #CG-#%#33
Ѐ@ڀĀ€!5CG5! ȀԀ`';KOC/#!#€    ΀ -;3+#@#'#'倰΀`ڀ#+1% )' ؀ʀ@ )CWSGC=-@')' ̀@ԀЀ+-!#1173ʀ܀@@ 1C;7;1 '7=9؀̀ĀЀ%/791)''191#Ҁ)?OK?95! @ !13#Ԁ€ƀڀրЀԀ%+3=7/1/-+#)#퀨΀ @1KWK?;- +13Ҁ؀ր'59?=/))'-1) ;S[WK?- %%@؀ʀ'1-)%#+79#造'1377;5`#+#ԀԀ !/73)%1CK;@ #;=?CGC+@ %;?瀸ހ@)9=5)3CG1 5?73375)@ /-ƀր'9?;?CC1̀΀8995))591+-) ƀЀ  3?KKC?;񀸀ƀڀ5=999;;9++797%܀ʀ܀ހր؀ !)5CKSOC9΀Ȁހ-=GW_W?%#%Ԁ +COG=-؀ %'%-9GKO[WC/@ހȀȀ  )##1?KOG=+ڀ ` 1K__S?;;-#/1ހ %-/;=;?3!րʀȀ̀ +)'/1-7?KS?%%Ѐ` ;OK9-ʀ/#9G?95/51'')+΀ @%=KK9-Āրր܀!#%5?;)%%-/#+9;/ Ѐ =KC3#󀔀րހڀ%#+5;?1!+;/!+9;䀤  7GG;'`؀܀ր#/=C?1%-?1/?G-€ @  )CK?/ڀ΀֠7CC?1!'91#;O? Ā  `'CKG3΀ 7SS?')#3?OCЀ %#?K;% ̀΀'G[G-')!#7K[K΀@ `'- '?91'ƀ!@/W[?#!%-?_[1#/(@+/-/'# -!؀΀Ҁ[wc9 #-;;O_C € 177C-')'􀘀 )'؀؀Gc[= 9KOW_C €3/7#)5/!@)+܀7[[C 1CKS_K΀%;+ !3%+;5܀@59Ҁ3W_K;OWkkG@#9-@+5+;G7`?7΀/_gC`';Ogk?򀘀7O7'59KK/񀘀'O7瀸Owk- !GScs[!ЀЀ=C#??O_C!ƀ GC) ԀCcWڀ ?gs{{G!9++1?_[) ܀5C/ Ҁ΀'S[/րGcw{g#Ԁ 9?) !)G[CGG1Ȁ 7WG܀ /Ws{{S95 )-;WO%ʀW[?%Ѐ)KC܀5_w{{Wڀ==!-3GcS!倌Ԁ![cG+Ȁx#C; /_w{{Sڀ!C?%`+;O[G耐{{g-耐Ā;K_k_cc+€[{{g7)% Ȁ1c{{s?0ڐ7O_g__gGKw{o?1/'؀@'S{{wÒʀ3GWkc[gWր7o{sG57-ڀCw{{W#ހƀ`/GWkgck['_{wG535+`ʀ܀ʀЀƀ΀?{{{{sww_)܀ހ؀ƀ܀Ԁ̀ʀҀ؀` #//=OKC/)!@'-[{{{{w[O=1ȀĀʀK{{{{{wkO' ր€ȀԀ'95% #%+)@'g{gG)Ҁ)%+΀#Ck_WG7ҀʀȀĀЀԀހ@5G_{kOCCOO91`@  ` 15+995%` ܀Ԁހ##7751'` )@@@܀Ѐ=_kgOGWOG5+ԀȀȀ!!%+--3+)# @ހހ  '+7SSSC')!܀܀؀؀ڀހ-/C1++'  ހ@   ` @  `@@@@@@ @#!%!! @ @@ `@ @   p@    `@@p0@p@` ` 0@@  @ @ @0` `@x    `@@ @ p ``0@   @@@@@      @@ `p @   `@ @h`p  Pp@ @@@ @` ` @ @pP`@@  @ @@@@@@`@@``p``p @ ``@@@ `@0P@@`@@pP `@ ``0@p@ `@ @`p`@```@``@@@@h@ p X @ p` PP@ ` @  P`@`p@ @ P0Ph`@( 0@ `@`@@P` p0``@8`@0``@p8@`@@@`h@@ P@` p@P @@0  0@`p@@`@ 0(@@@ @@@`@0`h@PP` @H @@@@x`8  p0````P` `0  P0@@@`p`pPp@pX``@@@@8``0`p   `00 `@ P0`  @  p @``p@x@P  ` `P`@P`@@ @0@`p `p0`0p@0  @P`X`X0@X@0 ``@`@`pPp `0Hp@@@@ppP 0  P@@  @ P`@Xp`phP@p@@` PP  `@`` P(hH@0@@8`ppP0P0 ` `Pp8p@0P0 P@@@@p0 (`x@P``0@ P`PphXpP@@ @`@x@`@00 `0008p`hP@HP h`0P`0PP(P  HH `PpH0 (@xDK)(87F""""* =;5"AvKqp/X@WWWWWWWWW\\\\\\\\\WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\\\\\\\\\\\\\\\\\\\WWWWWWWWWWWWWWWWWWyyyyyyyyyym\yyyyyyyyyyqmyyyyyyyyyyyyym\`yyyyyyyyyyyyyyyymuyyyyyyyyyyyyy`uyyyyyyyyyyyyyyyuyyyyyyyyyymyyyyyyyyyymyyyyyyyyyyyyuqduyyyyyyyyyyyudyyyyyyyyyyyyyuuhhmhyyyyyyyyyyyyyyhuyyyyyyyyyyyyy\uyyyyyyyyyyyyyuyyyyyyyyyyyyyuyyyyyyyyyyyyuyyyyyyyyyyyymqyduyyyyyyyyyyyyq`yyyyyyyyyyyymyuyhhymmyyyyyyyyyyyy`uyyyyyyyyyyyyuyyyyyyyyyyyuyyyyyyyyyyyyyymyyyyyyyyyyyymyyyyyyyyyyym`uqyyduyyyyyyyyyyyyqduWyyyyyyyyyyu`uyyuyyhhyymmyyyyyyyyyy\yuyyyyyyyyyyuyyyyyyyyyuyyyyyyyyyyyyyym`uyyyyyyyyyyym`uyyyyyyyyyyym`yyuqyyydqyyyyyyyyyyyyqdyyuyyyyyyyyu`yyuyyyuyyyhhyyy`myyyyyyyyyyyuyyyyyyyuuyyyyyyyuyyyyyyyyyyyyyyym`yyuyyyyyyyyyyym`yyuyyyyy`yyyyhqyyyyddyyyym`yyyyhyyyyuyyyyhhyyyy`yyyyyyyyyyyyyyy`yyyyhyyyyy`yyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhyyyyyhhyyyyyyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhyyyyyhhyyyyyyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhyyyyyhhyyyyyyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhyyyyyhhyyyyyyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhyyyyyhhyyyyyyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhyyyyyhhyyyyyyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhyyyyyhhyyyyyyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyuWWyyyyhmyyyyddyyyym`yyyyhyyyyyhyyyyyhhyyyy`yyyyuW\uyyyyyyyyuWWyyyyhyyyyyhyyyyyhyyydhyyh`uyyd\uyyyyyyyqqyymWuyyyyyyymmyyhyyyyuW`yyyyhhyymmyyyyyyyuyyyduyyyyyyymhyyyyyyduyyyyyyymhyyhyyyy`hyyyhyquhhydmyyyyyyyyyyy`\umhyyyyyyyyyyy\WuhyyyduyyyyyyymmyyhhuW\yyyyyyyyyyyhyqhyyyyyyyyyyyWqyyqhyyyyyyyyyyy`uhyy`hyyyyyyyyy`hyhWW\\yyyyyyyyyyyyyyu\WuyyyyyyyyyyyyyuWyqhyyyyyyyyyyy\WuhWuyyyyyyyyyyyyyuWWWyyyyyyyyyyyyyyq\WWyyyyyyyyyyyyyyuW`hyyyyyyyyyyyyy`WdyyyyyyyyyyyyyyydhyyyyyyyyyyyyyyuWWWyyyyyyyyyyyyyyuW`yyyyyyyyyyyyyyy``yyyyyyyyyyyyyyuW`yyyyyyyyyyyyyyuWqyyyyyyyyyyyyyyyhyhqhdudymdyyyyyyyyyyydqyyyyyyyyyyuWqhhyyyyyyyyyyyyyyuW`yyyyyyyyyyy`hyyh`yyyyyyyyyyuWqhmyyh`yyyyyyyyyyuWqh\yyyyyyyyyyyyudhyyyhqyyhduyydyyymdmmmmmmmdhhhhhhhhWqyyhhyyyyyyyyyyuWqhdhhhhhhh`hyyyyyyh`hhhhhhhWqyyhmyyyyyyh`hhhhhhhWqyyhqyyyyyyyyy`Wuyhyyyyy`qyyyyhuyyyydyyyyydqyyyyhhhhhhhhhWqyyh`yyyyyyyyyy`qyyyyhdyyyyyyyyyy`qyyyyhWWWWWWWWmyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhqyyyyhhyyyyyyyyyyhyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhhyyyyyyyyyyhyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhhyyyyyyyyyyhyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhhyyyyyyyyyyhyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhhyyyyyyyyyyhyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhhyyyyyyyyyyhyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyyhyyyyyhWyyyyydyyyyymyyyyyhyyyyyhhyyyyyyyyyyhyyyyyhmyyyyyyyyyyhyyyyyhyyyyyhyyyyy\uyyyyhyyyyydyyyyyhuyyyyhyyyyyhdyyyyyyyyyyduyyyyhmyyyyyyyyyyduyyyyhuyyyyhmyyy`dhhhhhhhuyyy\`yyyydyyyyqdmmmmmmm`dhhhhhhh\uyyy\yyyyyhWhhhhhhhdmyyymmyyymdhhhhhhhuyyy`yyyyymyyymdhhhhhhhuyyy\dhhhhhhhuyyy\my`myyyyyyyyyuy``yyydyyyudyyyyyyyyydmyyyyyyyyy`uy`myyyyh`yyyyyyyyymmy`mymmyyyyyyyyyuydyyyymymmyyyyyyyyyuy`myyyyyyyyyuy`Wmyyyyyyyyyyy\`yydyyudyyyyyyyyyyyquyyyyyyyyyyyW\myyyhmyyyyyyyyyyymW`myyyyyyyyyyydyyy`myyyyyyyyyyy\uyyyyyyyyyyy\`yyyyyyyyyyyyy`ydyyyyyyyyyyyyyyyquyyyyyyyyyyyyymyyhqyyyyyyyyyyyyy``yyyyyyyyyyyyydyy`yyyyyyyyyyyyyuyyyyyyyyyyyyymyyyyyyyyyyyW`dyyyyyyyyyyyyyyyyuyyyyyyyyyyyyyyWmyhuyyyyyyyyyyyyymmyyyyyyyyyyyWdymyyyyyyyyyyyWyyyyyyyyyyyyyyWmyyyyyyyyyyyyyyyyyyyyyyyyyyuyyyyyyyyyyyyyymhyyyyyyyyyyyyyymmyyyyyyyyydmyyyyyyyyyyyyyyyyyyyyyyy\yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyuyyyyyyymhyyyyyyyyyyy`WyyyyyyyyyyyyyyuW`yyyyyyyyyyyyyyuW`yyyyyyyyyyuW`hhhhhhhWyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[`[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[`[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[^rshe`^[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[kMMM]b[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[gx_[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[zOOOO{[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[lf[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[QQQQ[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[qf[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[TTTT[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[he[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[|WWWWde[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[hd\[[[[[dd[[[[[[[[[xxxxxxdddddddddccdddddddddddddoYYYYYddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddkfddddddccdddddddddxxxxxxdddddddddccddddddddddddds_\\\\ddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddjeddddddccdddddddddxxxxxx[[[[[[[[[dd[[[[[[[[[[[[[______[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[gd[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[aaaaaaa[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[ed[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[cddddddd[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[cc[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[efffeeefa[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[cb[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[hhhhhhhhh[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[aa[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[akkkkkkkkk[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[a`[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[ilmmmmmmmma[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[ae_[[[[[``[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[oooopopoool[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[ddkzqga\[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[qqqqqqqqqqq[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[_{a\[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[ttttttttttt[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[~db`^[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[wwwwwwwwvww[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[{zuhd`\[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[xyyyyyyyyyyyw[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[zf[[xxxxxx[[[[[[[[[dd[[[[[[[[[[{{{{{{{{{{{{{[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[x[[xxxxxx[[[[[[[[[dd[[[[[[[[[[~~~~~~~~~~~~~[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[tv[[xxxxxx[[[[[[[[[dd[[[[[[[[[u[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[qm\[xxxxxxdddddddddccddddddddd{ddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddddddulfdxxxxxxdddddddddccdddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddddddslgdxxxxxx[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[jl\[xxxxxx[[[[[[[[[dd[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[al[[xxxxxx[[[[[[[[[dd[[[[[[[[w[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[goq}l[[xxxxxx[[[[[[[[[dd[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[^bgnt}j[[xxxxxx[[[[[[[[[dd[[[[[[[[{[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[adre[[xxxxxx[[[[[[[[[dd[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[u\[[xxxxxx[[[[[[[[[dd[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[}vx[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[~[\`fmt|\[[[[xxxxxx[[[[[[[[[dd[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[~[[[[[[\gkgpv`[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[}[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[e[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[|[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[edd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[~{[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[}z[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[{y[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[{x[[[[[[[dd[[[[[[[[[xxxxxxddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddddddddddccdddddddddxxxxxxddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddtdddddddccdddddddddxxxxxx[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[{r[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[ht[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[\`j{u[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd_hx{[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyxyyyyyyyyyyyyyyz|{xxxyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd\\\\\\\\\\\\\\\de]\[[[\\\\\\\]]]ed\\[\[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd\\]]\\\\\\\\\\\dd[[`j_[[\\\\]]]]ed\\\\\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd\\\]\\\\\]]]\\\dd\exo][[\\\\\\\dd\\\\\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\]]]]\]\[dimztjtrd[[[[\\\\dd\\\\\\\[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\\\\\[[[dytgadqylb`[[[[[dd\\\\\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[\\[[[[[[]ittfdafx~me][[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[]`dhnpha`bf|{xqcbcccc][[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[dmmqv|{lhlhcenwpnmptc[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[]lwppqwzlhzegqypjejtd[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[_ht\_]g{oirnfgxwnfbgue[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`hu]``lqhbbdgytoldfve\[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdfju`elt{pdcfp}wyfgweddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddddddddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdeju_mwrzpebgn}wuzffweddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddddddddddddddddddccdddddddddxxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`iu]gll~tgbabdtmjfdfvf][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[ahu]`alpgcadftmihdfuf][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[ahu]ablwrqptynjgafvf][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[agt]abnwpnlnnhgdeug][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[agu_cen||rtyxtohfbetg][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[aht\bfp{|ngdbftg][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`ht]`bqurnjlcetg][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`ht]ditzgmpzdfqg][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`ht_lwzlolndgtf][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[_ht`foztdphedfue][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[_ht`agxodplhdfue][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[_ht_agxjc~pjhdfuf][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`ht]agxwllu~qjhegvf][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`hr]`gu{jmf{olhdfwf][xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`hr]`hvyy||fdlynlfdgwg\[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[[[[dd[[[[[[[[[xxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdejt_ap}xuwlmnvxwvtghwgddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddddccddddddddmdddccdddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdfjt_fz}tu~pmnjuwvzegwfddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddddddddddredddddefffgdddccdddddddddxxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`ht]g~xprt{~tlzwnmpdfuc\[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[\fig_^aeknmn[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[`it_bnwtqx{}zznhdcgvd[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[\hxppwm[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[_ju_`gtvt{yqpnzmhdchvd[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[\[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[]hu_ahuywxwfjgu{mhdcjud[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[d][dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[]et`ahtyz{|zthplpylhecjvd[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[u[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[bqaagpu{}~wyyjphmzwlhgblwb[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[`x[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[awgajrux~{|~ptmw{~|xlhgctv][[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[mw|sjn`dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[`uj_gpru||vxrz}wqnru|{{utqgdwq[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[_}kj}dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\pt_etytxx~whhhebadg~wxuwwfjzg[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[izaevwtvzzrmjdadcdlyqutmmfr{_[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[]}emd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[`ztdnprux{{u}ofbaedcg~{tntrlljzq[\[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[}d[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\[m~lptrwyxwuttngadhhddt|zzyupttmpx|`[\[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[}d[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\[]xtwuwwuuttqjlolnjfmtuuz{ztuut{p[\\[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[}t[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\[g{||{xvtvqhjt{yqnppru{~yz|~]\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\tzvwtjfhmtollprxe[\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[uu][[[[[[[[xxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddedde{xvqppqquy}zdddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccddde{ddddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddeeddj~{zxwx~edddddddxxxxxxdddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdddddddddddddddccdd{mddddddddxxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\[`|zyz][[\\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[l`[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\[[\\\[`~f[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[le}[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\[[\\\[`zhd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\[[\\\\[`x|{add[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\[[[[\\[[hz~w[[dd[\[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\[[\\\[[`t~}i[[\dd[\\\[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\\[[[\\[[dlpzwa[[\\dd\\\[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\\\\[\\\\dd]al~td\[[\\\dd\\\[\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\\\\\\\\\dd[[\`lrd][[\\\\\dd\\[[\\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\\\\\\\\\dd\\[[[\[[\\\\\\\dd\\[\]][[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[\\\\\\\\\\\\\dd\\\\[[\]\\\\\\\de]_]\]\[[[xxxxxx[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[[[[[[[dd[[[[[[[[[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/LB\^Irk6:Bش!L4tttttt:B؆tttt=$:e=$:e=$:e=$:e'w4Eamx#t ֮R> Y{#U> YI~taggedtaggedtaggedtaggedtaggedtaggedtaggedtagged tagged tagged tagged tagged taggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtaggedtagged]easilyeasilyeasilyeasilyeasily3]tagged3tagged3tagged8]tagged8taggedH]taggedQ] was tagged.h] lost all by himself.C] was tagged.t] fell in the water.B] was tagged.F] was tagged.G] was tagged.Y] was tagged.X] tagged himself.W] tagged herself.uvVJJ]*)FriendlyBotAPI.FRemoteUTBotConfigSClientfLo]Friendly Remote Bot CTFImR"* + &UlFA:Cd<%Nb31.BMd2 ,av`+ZU> Y{#U{#U{#U{#U{#U{#U{#U{#U v]'s streak was ended byw]*)was looking good till he tagged himself!x]+*was looking good till she tagged herself!]is scoring a lot!  is amazing!x9O0 TofHQ Z{`OK$vA\O[z}@D7SdRY4VW]5[h_>jrp 6a3Ui8ԝXԝX5Mis the master!is the master!is defeating the competition!(&-,')%*g\eUn]FriendlyBotAPI.Wiz.2$A]Wizard0]%$FriendlyBotAPI.FriendlyVoiceMaleOneP@jqIJKk=gPn`rBJAcѿT5ѿ?V5@?44)*@ѿT5ѿ?V5@?44)*@+^ѿT5ѿ?V5@?44)*@X@@@@@X     %%$-+ $'    C -+.!4 %8 "  >&?*[3MN/;.0$,'\|y$sJ#( HHc#F6bF5gD IUYVXW4 R@o m))pqQQnA/}0O7-+1PZfC;9zCG,w{x'8&[%]&'sDhdegi> D1Pf-+O7{/0}wx,.M/N~\y0|}$O7-+Z GZ C9 f4IXVUW3KLYE;a!T_2<`=S ;9El />K="TcI#JIX)46)WY6VdZ57$7$3UG;rc# _pd@ no;jr?f_ p@ enEo V@FU?X)WR+fQ2:T*M2PAe<N{EOBSa`T"LwlvkM3ubqJX4 WY VZ5s++**iQqQhRRSSBBs AA $iH !. 0h1g-!,!K"[# D$H!.C01g-,C/"[# D'%j&(9^mmt\(89^~''-t \-(18 }~1- yO-01 z} 01xy NO/0]z /0|x  PN/'Q+R%W])XUF@/VBO{|N <APP(M*T:&SGa=`LwlvkMuUb>D2CIHKIFLFHDL=4=;9;4<9<76:65:8?82?3>G>GJJECEK753l v@00???^aa ]7`7] 7  66 464 t4tBuBB888OO3N3;3;;99b9bQ2c2Q:2:Q:@d@d00d0``??` ?  55a`4V`V77V_7__UU66US6S44S 4 tu"fufBBfBXX88X 8  ONYNY33Y+3+;;+[;[[99?9?bc@ZcZ22Zc2c::cX:XX@DDddDd```   544VVVVV__V_UUUSS=S= ">"fffXXsXs  s YYY+++[[[?@@ZZZcccXXXD,DDD,+++E..D.-V-V-P(|=|(=|'>'>'*FsF*sF!s!s!0&OO&O###%%))){535A7A1=1:G:$MLM$ JKHHINIL>><<5h]53h3Sh3ASAQSA7Q7^Q71^1 ^1= = =; :W :GWGeWGMeMTeMLTLRTLRbRJbJbJaKaKTaKHTHTHgIgIgINN N x xUw>U>U>\<\<v\<v]v5]]]hhhSS1SQ1Q1Q^^u^ u u   WWCWeCeCeTTTRRRbbYbYZaaaTTTggtgtHt H rG xrwqwUUUM\M\M\vvv]z1z1z1uuuCCCwYwZxZ\\\0tvtvtHGGrqq(M(M(Myywx\\vv))VVP{-qqmm..hh$$,,-ggg!!on njj//j/}""ik#knn%%n%rpp((,-)-ggg!  lljjlj}}"##ppnnpn{{z**()+)iillilooppop{zz''*+&+BBAkkiikimmoomo''''}(&(&|(PPP--.DBD.BDAA+k+k,k,k,)$$$~~~"#O&m&Om&-m-m-  E**F*{{{)@@A3A171;=;MGM$L$ JHKHIINK>><<5__ %   %% JJRRRJo  ! %&')*-./(4 63 :;!=>ABCD/GJL(PQ1 =<@Z\]^_`9defghijklmnopqrl#&xz{|}~A|-0P$&IKIdfs.05/6W,MH'(E88:28{| YZ^Q#$*jBC"623aO>[Y1KLm?X 5 yReg}~qr&)dg7cNt3b;7E0$-DSTU4 +@vv U XT"S A{FGH}EpqmnhkmoqrVZMYsuMq1tV=z*,A' }(#B!g{()()P{-PEF}\\vwIJ# O_R-0"O|{FPDoeB&XSl,=qKNs>B#JY"eXc{ {4\,< iU (G Uz  . o& gK L N N  <%*@IJ<=y,2nnKMSl(zLSNte >[E`'9<*$c4 &X 1!!!B""#~##$&$$e$%%^%%m%&&&'' 'e'(()Et*Nc**"+I+e+˷,b,m,-m-e-Ȕ.^F.mo.p./n/ӑ/0J0ִ0ߵ1g912 22BU3 3q3X34s4PV456w7%7e88 89L9:&;b!;nM;N<<8==7y>9>T T:cUZnU&UVxVZVWW ^WPX\zX-XYlYT\YZWvZZ.[[b[\m\]]^__:``7aa8nbcdp;ef&Xf4g _hLi:jjkuk4lmw*n(opKq(rr"sstBau#vmwblwȔxbx˷ynyz`"znMzP{bF{p|J|}}~^~m ioJ跂n蓃&ڄBk<{{q@hFF\>W:eKS(r.e\kKKGf)+Ke%R׭k%/s(GnD|I&'0j,&Zٻ%DΑ׿nҴimiiiSl(Q.(Z4&IUML_"nMKLT~%OWʒo͵  ` k g>r<:1MxL}"bm:[:OOp;@QnM*9;j9.R<%TLnJ&n'`FnёԴ`l`` J kn k  kkmngmgggϴn̑VwT| %K U!!."Ux"#'H#T$K%L&'iK(K)fK)*M*+0,3-%R.//&V0'Y1s1QU2z2LQ33L4\45\y56[67Xd7 88U9[n9::Q;q;X<<G==GQ>l>U[?L@lLANB8nCBD;dE;FBVG8H7I>\J7zK>LgKLM^"MmLNb"NOOkKPQLRMSTKULVKWJXsN>? >Xcu>O=@bu>/'@3>q4@"҃-8i?D>Т3@)'?T?5"@T?rJ?5"@1f>'?"2J?5"@,JD*?냭=>%?Lg>+>"?+>buP=@cu*'@Ԣ3 '?Bg c@b!S<@Ã-D>7i?ڃ-"%?f>rq?9&YpD+??H7Vc4O=@>è^5"@dJ?DQ=@->c>@b> T5"@T?fᾍ@"G >@Q ">(?gᾶ=9i??8g*?>>O=@p4D>'?=*Y5"@JҢ3@<'@D?/R=bz=R5"X=>5"9&]4>5"sK=D?@Bg@>@Hg>]4>YsK= b=]4>}rsK=Rsq?N=>r9&𿽚Y9&cu>8i?"cu>Ѿ5"@5?5?5"@ѾR>5"@sC?ƒ-?@w 3@-?]4>bsK= >5"TH7>&?pDf'?" ?=55"@ѾQ5"@6Ƣ5i?6L >%?K >B @E >>@%g>?G4''*?U3&7i?=]4?K+'@3>3*?;'3>@4'nQ>5"@̼CD@ƃ245"@wJuQ5"@ռC?R}rX=>RYX=>]4>sq?sK=4O=@"?@(* >@8 >Ѿ5"@555"@>Y~/?5"@f>̼C?5"@Qz>5"@C~/ͼC?5"@PQ>o>5"@X~/?3*?&'> 5"=/R=sq?z=0R=5"z="?,?E T5"@ TǞJ5"@+YʞJ5"@*Y>Ã@DD?@>ah48i?>>9i?L{D>'?D>O=@-0P=@bu4i?cu@ @-?Ã-?@D4Pz5"|*?Hg>"*?f>+?">@\g"(?f^ @"?]45"sK=b@b>c>@b>D?@ }r= Y=/R=rz=񿽔?9&> sq?=/R=Yz=𿽿b9&RbN=>=5"9&> >rq?R >YR >rU >bT]45"K+'@3Ã@D c@ c>˃>@D?c>@bʃ-@%>@D14@˃-3'?@3>3@.'?D@>3>@5'?D@>3@/'@D?c@c-@ `4D@ك3'?@3Ճ->P=@D19i?Ѣ]4>?bK=3>@&'D?@>>@D?5'?@3/'?@3> c>@bŃ>@D3>@)'?R=?T=>pD=%?$H7E @T f>@"P >*?K f>@">"@g>r1$?">@8g`g>$?>">(?f>B *?% >D_2*?"?fᾋ@">"@"@f!>(?TgE *?Q :g>@ڹ>Wg>@ f'?">Sg*? ">@fFg>*?">@f>2g@]4rK]4b⿸K]4sq?K]4YK=sq?9&>=b⿺9&>=}r9&>=Y9&>ᢳP=@>D>4i?->ۢ=P=@'>O=@2}3=$?'>->+?oWc'?bH7'?pD= >?~pD#? H7>𿽒?9&-(?dڳm'?-]4bsK=]4rsK=]4sq?sK=]4YsK=?>5"|񵴓]4>5"K 5"T5"9&>0R=5"N=>=5"9&/R5"z= >5"=?5"|5D8i?ƃ->Ԣ8i?1>ʃ->9i?D8>O=@뢳=>P=@=ŃQ=@98>O=@΢=7i?.>0>7i?Ң->8i?=cu>Q=@cuD9i?҃--P=@DcuQ=@bu>-9i?Dcu5i?bu>-O=@D>DO=@ރ-->P=@D>47i?Ńσ9i?4σ->9i?D>D>N=@؃->=P=@4cu>8i?buփ=*?D+,?,?>}r|?>Y|?>sq?|?>b|񵴓]4>}rK]4>bKrq?9&> sq?U]4>sq?K }rR YR bRr9&>𿽘Y9&>𿽿b⿹9&>]4>YK/R=rq?N=>/R=}rN=>/R}rz=/R=YN=>/R=bN=>0Rsq?z==sq?9&=}r9&/RYz==Y9&/Rbz==b9& >rq?= >b= >r= >Y=?Y|5?rq?|5?}r|5?b|5҃%?D>1'*?3=̓'?Dj.?->>c'?b=D(?=?9&?? m ?>?ĕ=?9&>'4?n=*#>?0=X#>?Sc=+?c=*'>*?G3=g3=$?<'=(?D>b=%?b<'>%?3*Y>5"@ʞJ?k5"@Q?*Y>5"@ʞJQ?5"@qƞJ?5"@+Y>ŞJ?5"@'+Y.J?5"@6J? T?5"@T5?5"@>>5"@5Q~/?5"@ʾ#N5"@Q*Y5"@J?>5"@5?k#?om4?O=>3#?e=uC5"@R>R5"@sCT~/5"@h>2J5"@(Jlʾ5"@P~/?a~/5"@^ʾϼC5"@bQ/J5"@3J?qJ5"@״yʾ5"@R~/& >?=hQ?C=>+'?+>`qD=%?G7>]4>?K+>(?+]4?K=H7>$?>pD= ?,+H7&?UqDuR=?e=R?=<5?5?_ϒ<_=@55jT?%XXXp  < q O  I7 !"#$%&' ()*+?,-./011_234567#8 9b:;<=>?@ABC̜D=EFG6HIJKLMN4OPQRSTUVWXYZ6[\]^_`abcde~fghi'jkl,mInopq7rstuvwx.yz{|7}~=!=ܚR-\(\q(,;DŨE,  ]]'_@##.1 ?    74;!=,˜ !"#<$3%&Y'3()_*_+h,{-D./h0{123456789:;<=>?@ABCDEFGHIJKLEMNO-PRQORSbTUVW"[{ b {  {{z{P{ WX!"#$ %&'()*+, -./ 01234567 89:{;@<=>9!?h{@ABC3cD#ERFG_HIJKLMNO PQRSTUVWXYZ_[\]^O{_`abcdF efWXghi"jklm{n{o[{pq{rstuvw!xyz"{|} ~   #h{{R{z{{{{{{{R{"  \9Wb<"XcR^ "g#9!hPg#""F #h[$   !             " a3c a!R^"b#b$%S&'()*+Y,W-\.[/Y0W123456789:;<=>?,@A,BCDEFGHIJKLMN$OPQRRST@U<VWp @ cbu>@0,?3>N @ ϒ<"??>D>@E>)'?@T?@ F13?:ؾ"@ ,J3?(>냭=3?6Lg>?У+>@vރ>cu@0,?Ԣ33?>Bg@>b@ϒ<Ã-?ڃ-3?O>f>>=9&?=?H7@/ϒ<>@В->M @ 6b>@?T?O @>"Q @LݮQ 3?qgι??3?J?>@Vp43?=@Єk>JM @E><'N @>D?:poz=3$N=X=>3$=9&2$"sK=P @&O @J?>P @>Hg>"sK=:b%>="sK=>N=N=>=9&=9&? c"cu>@>5?@1Ѿ@?sC?Q @E(wS @jϒ<-?:濰"sK=2$&T?&$pD3?>"Hk?c%>=@@:?Ѿ@ [V?6ᳺ?V=63?RݮK >N @=7>E >N @L%g>5? ВU3?ǰ>=Lk?F>KM @0,?3>3? }=;'L @H!4'@xp?̼CN @?ƃ@ΒռC?N=X=>N=X=>>"sK=@ϒ@>5@@:?>@*f>@N&?Q@wC~/@O&?PQ>@twX~/?3?m }=&'>4$b%>=>oz=3$oz=3?E @? T@E5O?+Y@H5O?*Y>N @>DP @,>?ϒ<>?VL{3?@-@*ǰ>?pރ>cu@ϒ<-?@F(D42$ ϒ<|񵴯3?>Hg>3?V?3?:ؾ">P @>\g3?O>fR @В<"?3$uF>sK=@>b>@6b>@b%>=b%>=oz= ?=9&>>b%>=@oz=:濦=9&:濔N=N=>3$2=9&>>R RU:#T3$uF>KO @0,?3@>DM @> c>O @VD?Q @6b@G2?%O @VDO @Mϒ<˃-M @#3>N @E>.'?O @!?>Q @H!5'?@?>@E>/'@>D?M @>cO @;2? `4@?كO @#3@)D?*ǰ>ѢHk?"bK=@H!&'@">@VD?@#3@#3>@6b@VD@H!)'?Jk?0oT=>?$H7O @@7>T N @9ؾ"3?VݮK O @9ؾ">J @O>g>3?ϒ<"Q @D8g3?f:>3?qf>3?<7>% >3?ϒ<"?M @>">M @K?P @O>fᾭ3?ZTg3??7>Q P @?:ڹ>N @\: 3?>">3?&J? O @qfᾯ3?L:N @qf>O @J?F>K:zF>K>F>K{F>K>=9&>:,=9&>=9&>$=9&>@V=>?->@'>@V=23?^uԼ'>3?)oW3?v >b?I>pD=Jk?? = H7> ?=9&3??>dڳ3?ϒ<-:zF>sK=F>sK=>F>sK={F>sK=2$-|2$"K4$b%>T3$=9&>3$oN=>3$=9&2$N=z=2$1=3$JR>|5?q>ƃ->?V=1>?)D@>m뢳=@8ǰ>=@>9@>m?.>?7mҢ?4m=@$ ccu?q>҃-@?>D@ރ>bu>??>D?|ރ>bu>@?>D>@q>ރ-@)D>?Β<Ń?Ȱ>4?)D>@؃->@4? cbu3?ψD?>,-|-|>-|:-|񵴪"K:濰"K>=9&>>b%>U>"Kb%>Rb%>R:b%>R=9&>=9&>:濦=9&>"K>oN=>oN=>ڹN=z=@oN=>:poN=>>N=z=>=9&=9&ιN=z==9&:¹N=z=:=9&>%=:/=)=+=JR>|5>JR>|5JR>|5:JR>|53?7=D>3?%9>3=3?7=D3?;В<->3? >b=3?(> ?,=9& ?JR> m  ?-ĕ ?4=9&>yR?3ϒ3?нb3?H@3@FʞJ?@HВ@GF'+Y@ 6J?@T@1>@Ⱦ5@*ʾ@ϒJ?@Ⱦ5?xR?\ 6>orR?ΒsR?$ 6>e=@JH?R>@td>sC@4?h>@?(J@g>P~/?@4?^ʾ@MSH?bQ@?3J?@:O?״@t>R~/Hk?5=Ik?+N=C=>?Dž>+>?:G7>Kk?"K?+Lk?sF>K=?*$>pD=Kk?b%>,?I>UqDNk?Ȫoe=Pk?N==! c>=bu>0,>3>ϒz>"?޾D>E>)'???T? F??1:> ½" ??,J( ½냭=8= ½Lg>̣==+>wރ=cu0,>Ԣ3 ½Bg>bϒ>Ã->޾ڃ-O ½f>Ƥ,29&솽t=?H7-ϒ=>В ?dJ?q=->6>z>b> ?T?꾰z>"Oݮ>z>Q q> ½g=޾?J ½>V>=p4> ½=Єk?JEz><'z>D?o<Ԧqz=ҹNUX=>Ƥ佴U9&">UsK='?z>Jz>>z>Hg>">@@sK=b%Ԧq=">sK=ҹN,2N=>Ȥ佫9&Ƥ@@9& c>޾"cu>ھ?5?1? ?Ѿ?>?sC?F(?z>wcϒz>-?">ԦqsK=>UT%$>~=pD ½"c%D;=@:?Ѿ [V ?6ᳯVؽ޾6Tݮ> ½K >=7z>E >P=z>%g>*ВDG49 ½U3!ǰ޾=F<;K0,z>3> } ½;'H!>pz>4'|p?>?̼Cz>ƃΒ?wJk$d?ռC?ҹNX=>ҹN?@X=>">,2sK=ϒ=>z>(2ݮ>z>8 >ھ?5@:?>*??f>Q&???Qw>?C~/R&???PQ>ww>?X~/?p } ½&'>b%U=o<,2z=o ½E ? TF5O?+YI5O?*Y>z>D-?z>>+ϒ޾>V>޾L{> ½>=-+ǰ=rރ޾cuϒ>-?G(?>D4ϒU| ½Hg>W ½:> ½">z>\gO ½fᾲВz>"?FUsK=>b>6>>b> ?>b%=b%?@=o<z=佢<9&>b%,2=o<@@z=ƤԦq9&ҹNԦqN=>==U9&>>,2R>@@R>U>ԦqTFUK0,z>3>Dz> c>V>z>D? 6>z>bH2>%V>z>DFϒz>˃-#?z>3>Ez>.'?"z>>H!>z>5'?>>E>/'>D?z>c<2z> `4 >ك#?z>3)>=D,ǰ޾Ѣ">D;bK=H!>>&'#?>>V>>D?#?>3#?>3>6>>bV>>DH!>>)'?o<@;T=>t<=$H7@7z>T 9>z>"Xݮ> ½K 9>z>">O`z>g>ϒ ½"H=z>8gh:> ½>q> ½f>=7 ½% >ϒ ½"?꾐z>">Lz>Oz>f\= ½Tg@7 ½Q B:>z>ڹ>_:>z>  ½">'J ½ q>z>fN:> ½q>z>f>Jz>FKFԦqKF,2KF?@K==,29&>==Ԧq9&>==9&>==?@9&>Vؽ=>>޾->=='>Vؽ=2^u< ½'>)> ½oWx ½bI|=pD=>@;(솽= H7>Ȥ佦<9&? ½dڳϒ ½-FԦqsK=FsK=F,2sK=F?@sK=->U|񵴡">UKb%UTƤ佴U9&>o<=U9&NUz= >U=JRU|5q޾ƃ->Vؽ޾1>)>޾D?m>=뢳=9ǰ===9?m>==޾.>7m>޾Ң4m>޾=& c>=cuq޾҃-?=Dރ=bu>?޾D~ރ޾bu>?=D>q=ރ-)>=D>Β޾Ńʰ޾4)>޾D>>=؃->==4 c>޾buψ= ½Dr=,->|->@@|->,2|->Ԧq|񵴡">K">ԦqKƤ,29&>b%,2U">,2Kb%Rb%?@Rb%ԦqRȤ佫9&>Ȥ@@9&>ƤԦq9&>">@@Ko<,2N=>o<N=>Nz=oo<ԦqN=>N,2z=<=,29&<=9&N@@z=<=@@9&NԦqz=<=Ԧq9& >,2=!>Ԧq=!>= >@@=JR?@|5JR,2|5JR|5JRԦq|57ҽ ½D>&9 ½3=7ҽ ½D>В` ½-> ½b=( ½(==<9&JR< m -><ĕ0==<9&>Kϒ>n=7Y>>0=eY>>S5= ½c=7@> ½G3=2u< ½<'ψ= ½D>= ½bI@> ½3F>?ʞJ?7В ?Q? F> ?ʞJ.M??qKF??+Y>JF??'+Y ? ?6J???T1??>>?5*??ʾϒ?Qk ?J?>?5?` 6>oϒ>O=>( 6>e=JH?R>td ?sC4 ?h> ?(JhӾ?P~/?4?^ʾMSH?bQ?3J?:O ?״uӾ ?R~/3>D;=9NB;C=>˅|=+>$<=G7>">>;K=z=+wF<;K=)$>=>pD=b%>;, I~=UqDo<8;e=N4;=]???tCt6~dNR5]! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot" !FriendlyBotAPI.FriendlFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot# "FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot# "FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1Bot! FriendlyBotAPI.FriendlyMale1Bot#"FriendlyBotAPI.FriendlyFemale1BotU_FGw"B#l  """"* * "=j/ E@ }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}r}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}믯r$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}D믯r$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}naaa$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}xaaa$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}xaaa$$$$$}}}}}}}}}}}}}}}}HHHH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaa$$$$$$}}}}HHHHHHHHHHHH HH}}HHHHHHHHHHHHHHHH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%}}}}}}}}}}}}}}}}}}}}}}}}}}}}iaaaaa$$$$$$$$HHRRRRRRRRRRRR$$RRRRRRRRRRRRRRRRRRRR}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa**%}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaa$$$$$$$$$R$$$$$$$RR}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa***$}}}}}}}}}}}}#}}}}}}}}}}}}}}aaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa***$$}}}}}}}}}}---}}}}}}}}}}}}}aaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$A|aaaaax}}}}}}}}}}}}aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$Aaaaaaax}}}}}}}}}}}}aaaa|$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$Aaaaaaa}}}}}}}}}}}}aaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$Aaaaaaa}}}}}}}}}}}}aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$*aaaaaa}}}}}}}}}}}}}aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$*aaaaaa}}}}}}}}}}}}aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafA$$$$$$$$$$$aaaaaa}}}}}}}}}}}}aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$|aaaaaa}}}}}}}}}}}ۈaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaa}}}}}}}}}aaaaa6$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5$$$$$$$$$$$$aaaaaaa}}}}}}}}}aaaaaa5$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5$$$$$$$$$$$$aaaaaaa}}}}}}}}}^aaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5$$$$$$$$$$$Aaaaaaaa}}}}}}}}}^aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$5aaaaaaa}}}}}}}}}}}raaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$|aaaaaaa}}}}}}}}}}}}aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$aaaaaaa}}}}}}}}}}}}aaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$aaaaaa}}}}}}}}aaaaaaaaa6$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaa}}}aaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$5aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$5aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}RRR}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$6aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$6aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$R}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$5aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$$R}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$^aaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$$R}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$AaaaaaaaaaaaaaaaaaaaaaaajA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$R}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$R}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$$R}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$}}}}}}$$$$$$R}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$$}}}}}}}}}}}}}}}$$$}}}}}$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$$$$$$}}}}}}}}}}}}R$$$$}}}}}$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}H$$$$$$$$$$$$$}}}}}}RR}$$$$}}}}}$$$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$ aaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$$$$$$$$$$$}}}}}$$R$$$$$}}}R$$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$$A$$$$$$$Taaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$$$$$$$$$$$$$$$$$}$$$$$$$$$}}$$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$$jaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}a$$$$$$$$$$$$$$$$$$}$$$$}$$$$$$}}R$$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$A$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaa}}}}}}}}}}}}$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$H}R$$$$$$R}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$$$aaa}}aaaaaaaaaaaaaaa$$$$$$$$$RR$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}$$$$}}}}}}}}}}}}}}}}}}}}}}aaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}$$$$$$R}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$$$|aaa}}}}}aaaaaaaaaaaa$$$$$$$$$}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}$$$$}}}}}}}}}}}}}}}}}}}aaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$H$$$$$$$R}$$$$$$$R}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$$aaaa}}}}}}}}}aaaaaaa$$$$$$$}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}$$$$}}}}}}}}}}}}}}}}aaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RR$$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$aaaa}}}}}}}}}}}*^^}a^$$$$$$}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|}}}}$$$$$$}}}}}}}}}}}}}}aaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R$$$R$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$$$|aaaa}}}}}}}}}}}}}}}}}}}RRRR}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$}$$$$$$$$}}}}}}}}}}}}}aaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R$$$R$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$5aaaa}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$}}}}}}}}}}}}}aaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R$$$$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$aaaaa}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$}}}}}}}}}}aaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R$$$}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$aaaaa}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$RHH}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$}}}}}}}}aaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}R$$$R}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$aaaaa}}}}}}}}}}}}}}}}}}}}}}}}}HRRRRRRRRRRH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$}}}aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}R$$$R}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$$$$$aaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}HRRRRRRRRRRRRRRRRHHHHHHHHHHHHHHHHHHHH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}R$$$R}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$$$$$aaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}$$$}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$aaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|A$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}$$$}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$jaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|A$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}R$$$R}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|T$$$$$$$$$$$$$aaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|A$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}R$$$R}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$$aaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$$aaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$R}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$}}}}$*aaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$}}}}}}}}aaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafT$$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}R$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}R$$$R}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}$$$R}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}R$$$R}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|A$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}R$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|A$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$$H}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}$$$$}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}R$$$$}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}$$$}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}R$$$R}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}R$$$R}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$R}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}$$$$H}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}R$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}R$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}R$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}aaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$Aaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$H}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa|$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$*}*aaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$}}}}}Raaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAAA$$$$}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAAA$}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAA}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaj$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}eeDeq}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}**a쮮}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}HHHHHHHH}}}}}}}}}}}}%**faaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}RRRHRRRH}}}}}}}}}}}}**jfaaaaaaD}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaa$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}}HRRRRRRRRRRRRRRRRRRRRRRRRRRRR$***faaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaa|$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}HR̩$$$$$$$$$$$$$$$$$$$$$$$$$***faaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaAAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaAAAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R^^R%AAA$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}$^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}aaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}RRRR%%A%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}$$^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}H$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaaa)}}}}}}}}---P%%%%}}}}$$$$Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}HR$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaaa}}}}}}}}af***$$$$$$$$Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}HR$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaa}}}}}}}}Daf***$$$$$$$$AAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}HR$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaaaa}}}}}}}}Daf***$$$$$$$$AAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$RH}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$|aaaaaaa}}}}}}}}}}}aaaaaAAA$$$$$$$$AA|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}HRRRRRH}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$5aaaaaaa}}}}}}}}}}}aaaaaAA$$$$$$$$AA|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}HHRRRRRRRRRRRRRRRRRRRRRRHHHH}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Aaaaaaaa}}}}}}}}}}}aaaaa|AA$$$$$$$$AA|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}HHHH}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Aaaaaaaa)}}}}}}}}}}aaaaa|AA$$$$$$$$AA|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaa}}}}}}}}}}}aaaaaa$$$$$$$$$$AA|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaa}}}}}}}}}}}aaaaaa$$$$$$$$$$AAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaa}}}}}}}}}}}aaaaaa$$$$$$$$$$AAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaa}}}}}}}}}}}aaaaaa$$$$$$$$$AAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A|aaaaaa}}}}}}}}}}}aaaaA$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$A5aaaaaaB}}}}}}}}}}aaaa|A$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$AAaaaaaa_}}}}}}}}}}aaaaA$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$AAaaaaaa_}}}}}}}}}}aaaA$$$$$$$$$$aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$aaaaa]}}}}}}}}aaaaaaA$$$$$$$$$$|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa