private void Reset() { level.Load(); Inventory.instance.Reset(); player.SetActive(false); portal.Appear(); timer.gameObject.SetActive(level.data.timer > 0); timer.SetTime(level.data.timer); message.SetMessage(level.data.message); aq.Delay(0.9f); aq.Add(() => { if (level.data.specialStart) { player.transform.position = new Vector3(-3, -3.74626f, 0); } else { player.transform.position = portal.transform.position; } player.SetActive(true); playerPS.Play(); if (timer.gameObject.activeSelf) { timer.StartTimer(); } }); aq.Run(); }
public void endGame() { gameOver = true; gameOverText.enabled = true; gameOverText.text = ""; lastScore = score; if (lastScore > highScore) { highScore = lastScore; PlayerPrefs.SetInt("highScore", highScore); } aq.Delay(1f); string msg = "GAME OVER"; int i = 0; foreach (char letter in msg) { aq.Add(() => gameOverText.text += msg[i++]); if (letter != ' ') { aq.PlaySound("click"); } aq.Delay(0.2f); } aq.Delay(2f); aq.Add(() => SceneManager.LoadScene("Main")); aq.Run(); }
public void SetMessage(string msg) { messageBar.text = msg; messageShadow.text = msg; Color startColor1 = messageBar.color; startColor1.a = 1; messageBar.color = startColor1; Color endColor1 = messageBar.color; endColor1.a = 0; Color startColor2 = messageShadow.color; startColor2.a = 1; messageShadow.color = startColor2; Color endColor2 = messageShadow.color; endColor2.a = 0; messageBar.gameObject.SetActive(true); messageShadow.gameObject.SetActive(true); aq.Reset(); aq.Delay(messageHold); aq.AddCoroutine(startColor1.LerpColor(endColor1, messageFade, (Color c) => messageBar.color = c)); aq.AddCoroutine(startColor2.LerpColor(endColor2, messageFade, (Color c) => messageShadow.color = c)); aq.Delay(messageFade); aq.Add(() => messageBar.gameObject.SetActive(false)); aq.Add(() => messageShadow.gameObject.SetActive(false)); aq.Run(); }
private void transferCoin(Transaction trans) { CoinBankAccount sendAcct = getAccount(trans.sendAccount); CoinBankAccount receiveAcct = getAccount(trans.receiveAccount); Vector3 sendVector = (trans.sendAccount == CUSTOM ? trans.custom : sendAcct.getVector()); Vector3 receiveVector = (trans.receiveAccount == CUSTOM ? trans.custom : receiveAcct.getVector()); // Only actually remove coin from transfer account if this is a transfer, otherwise just gain coin at main account if (sendAcct != null) { aq.Add(() => { sendAcct.value -= 1; updateText(sendAcct); }); } aq.Instantiate(coinPrefab, sendVector); // will select object aq.Add(() => { aq.Pause(); StartCoroutine(aq.selectedGameObject.transform.LerpPosition(receiveVector, animDuration, null, (tf) => aq.Resume())); }); // aq.Log("Coin from " + sendAcct.name + " arrived at " + receiveAcct.name); if (receiveAcct != null) { aq.Add(() => { receiveAcct.value += 1; updateText(receiveAcct); }); } aq.Destroy(); }
public void ActionQueueAddMultipleEntries_Test() { var actionQueue = new ActionQueue <BusinessLogicEntity, BusinessLogicEntity>(); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); Assert.AreEqual(5, actionQueue.Count); }
public void ActionQueuePurge_Test() { var actionQueue = new ActionQueue <BusinessLogicEntity, BusinessLogicEntity>(); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Clear(); Assert.AreEqual(0, actionQueue.Count); }
public void ActionQueueValidateEntryIsNotIn_Test() { var actionQueue = new ActionQueue <BusinessLogicEntity, BusinessLogicEntity>(); var entry = new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity> { actionClass = new TestAction(), dataIn = new TestModel { id = 100500, simulate_action_error = false, is_unrecoverable = false }, execStatus = ActionExecStatus.Pending }; actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity> { actionClass = new TestAction(), dataIn = new TestModel { id = 100501, simulate_action_error = false, is_unrecoverable = false }, execStatus = ActionExecStatus.Pending }); Assert.IsFalse(actionQueue.Contains(entry)); }
public void setMessage(string msg) { messageText.text = msg; transform.position = new Vector3(transform.position.x, startY, transform.position.z); gameObject.SetActive(true); aq.Reset(); aq.Add(() => StartCoroutine(transform.LerpPosition(new Vector3(transform.position.x, endY, transform.position.z), moveSpeed))); aq.Delay(moveSpeed); aq.Delay(holdTime); aq.Add(() => StartCoroutine(transform.LerpPosition(new Vector3(transform.position.x, startY, transform.position.z), moveSpeed))); aq.Delay(moveSpeed); aq.Add(() => gameObject.SetActive(false)); aq.Run(); }
public static void PlayCard(LbCard card) { if (!card.CanPlay) { return; } ActionQueue.Add(new PlayCardAction(card)); }
public void Add(TaskAction action) { if (action == null) { return; } tasks.Add(action); }
void VisibleObjectSpotted(GameObject visibleObject) { if (gameObject.GetComponent <Faction>().CurrentFaction == Faction.FactionType.Neutral) { return; } if (currentlyAttacking == visibleObject) { return; } if (currentlyAttacking != null) { return; } ActionQueue queue = GetComponent <ActionQueue>(); bool isEnemy = gameObject.GetComponent <Faction>().IsEnemy(visibleObject); if (isEnemy && queue.IsCurrentInteruptable()) { currentlyAttacking = visibleObject; switch (AttackType) { case Type.Chase: if (!queue.HasActions()) { queue.Add(new AttackAction(gameObject, currentlyAttacking)); queue.Add(new MovementAction(gameObject, transform.position)); } else { queue.InsertBeforeCurrent(new AttackAction(gameObject, currentlyAttacking)); } break; case Type.Static: queue.InsertBeforeCurrent(new StaticAttackAction(gameObject, currentlyAttacking)); break; } } }
public void ActionQueueRemoveMultipleEntries_Test() { var actionQueue = new ActionQueue <BusinessLogicEntity, BusinessLogicEntity>(); var entry = new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>(); actionQueue.Add(entry); actionQueue.Remove(entry); Assert.AreEqual(0, actionQueue.Count); }
public void ActionQueueCopyTo_Test() { var actionQueue = new ActionQueue <BusinessLogicEntity, BusinessLogicEntity>(); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>[] actionQueueArray = new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>[] { null, null, null, null, null, null, null }; actionQueue.CopyTo(actionQueueArray, 1); Assert.AreEqual(5, actionQueueArray .OfType <ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity> >() .ToList() .Where(c => c != null) .Count()); }
public static void OnNextUpdate(Action action) { if (!_patched) { throw new Exception("Not patched"); } _actionQueue.Add(action); }
void Start() { scoreText.text = ""; TransitionToScene tts = playButtonGO.GetComponent <TransitionToScene>(); tts.clickEvent.AddListener(() => SoundManager.instance.Stop("theme")); // Show long intro ONLY if this is the first scene loaded. // Otherwise show the fast intro. if (string.IsNullOrEmpty(App.instance.lastScene)) { aq.Delay(0.5f); float d = fadeTime; foreach (GameObject element in elements) { Transform tf = element.transform; tf.localScale = new Vector3(4f, 4f, 1f); SpriteRenderer sr = element.GetComponent <SpriteRenderer>(); Color origColor = sr.color; Color tempColor = origColor; tempColor.a = 0; sr.color = tempColor; aq.Add(() => { StartCoroutine(tf.LerpScale(new Vector3(1f, 1f, 1f), d)); StartCoroutine(sr.color.LerpColor(origColor, d, (v) => sr.color = v)); }); aq.PlaySound("drop"); aq.Delay(d); d *= 0.7f; } } aq.Add(() => updateScore()); aq.Delay(0.35f); if (!SoundManager.instance.GetSource("theme").isPlaying) { aq.PlaySound("theme"); } aq.Run(); }
public void ActionQueueIndexOf_Test() { var actionQueue = new ActionQueue <BusinessLogicEntity, BusinessLogicEntity>(); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); var entry = new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity> { actionClass = new TestAction(), dataIn = new TestModel { id = 100501, simulate_action_error = false, is_unrecoverable = false }, execStatus = ActionExecStatus.Pending }; actionQueue.Add(entry); Assert.AreEqual(1, actionQueue.IndexOf(entry)); }
void Start() { SoundManager.instance.Play("spiderDied"); game.spiderDied(); aq = gameObject.AddComponent <ActionQueue>(); aq .Add(() => StartCoroutine(sr.color.LerpColor(new Color(1f, 1f, 1f, 0f), 1.0f, (v) => sr.color = v))) .Add(() => StartCoroutine(gameObject.transform.LerpScale(Vector3.zero, 1.0f))) .Delay(1.0f) .Destroy(gameObject) .Run(); }
public void ActionsArePerformedOrderedByTimeThenByInsertionOrder() { var list = new List<int>(); var queue = new ActionQueue(); queue.Add(() => list.Add(1), 0); queue.Add(() => list.Add(7), 2); queue.Add(() => list.Add(8), 2); queue.Add(() => list.Add(4), 1); queue.Add(() => list.Add(2), 0); queue.Add(() => list.Add(3), 0); queue.Add(() => list.Add(9), 2); queue.Add(() => list.Add(5), 1); queue.Add(() => list.Add(6), 1); queue.PerformActions(1); queue.PerformActions(2); queue.PerformActions(3); if (!list.SequenceEqual(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 })) Assert.Fail("Actions were not performed in the correct order. Actual order was: " + string.Join(", ", list)); }
// After clearing the last message, you can then queue up another message public MessageBar queueMessage(string msg, bool hold = false) { aq.Add(() => setMessage(msg)); aq.AddCoroutine(outsideY.LerpFloat(insideY, speed, (f) => moveGroup(f), curve)); if (!hold) { aq.Delay(speed); aq.Delay(pause); aq.AddCoroutine(insideY.LerpFloat(outsideY, speed, (f) => moveGroup(f), curve)); aq.Delay(speed); } return(this); }
public void ActionQueueSetter_Test() { var actionQueue = new ActionQueue <BusinessLogicEntity, BusinessLogicEntity>(); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); actionQueue.Add(new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity>()); var entry = new ActionQueueEntry <BusinessLogicEntity, BusinessLogicEntity> { actionClass = new TestAction(), dataIn = new TestModel { id = 100501, simulate_action_error = false, is_unrecoverable = false }, execStatus = ActionExecStatus.Pending }; actionQueue[1] = entry; Assert.AreEqual(2, actionQueue.Count()); Assert.AreEqual(1, actionQueue .Where(c => c.Equals(entry)) .Count()); }
public void ActionsArePerformedOrderedByTimeThenByInsertionOrder() { var list = new List <int>(); var queue = new ActionQueue(); queue.Add(() => list.Add(1), 0); queue.Add(() => list.Add(7), 2); queue.Add(() => list.Add(8), 2); queue.Add(() => list.Add(4), 1); queue.Add(() => list.Add(2), 0); queue.Add(() => list.Add(3), 0); queue.Add(() => list.Add(9), 2); queue.Add(() => list.Add(5), 1); queue.Add(() => list.Add(6), 1); queue.PerformActions(1); queue.PerformActions(2); queue.PerformActions(3); if (!list.SequenceEqual(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 })) { Assert.Fail("Actions were not performed in the correct order. Actual order was: " + string.Join(", ", list)); } }
public void AddActionToQueue(Func <Task <bool> > task, string name, ulong bindedPokeUid) { if (task == null) { return; } var action = new ManualAction() { Action = task, Name = name, BindedPokeUid = bindedPokeUid, Uid = Guid.NewGuid().ToString(), Session = this }; ActionQueue.Add(action); }
public void startGame() { button.interactable = false; SoundManager.instance.Play("click"); // WTF, Color.Lerp is backwards? Durp! StartCoroutine(Color.clear.LerpColor(Color.white, fadeTime, (c) => { fadeCurtain.color = c; } )); ActionQueue aq = gameObject.AddComponent <ActionQueue>(); aq.Delay(fadeTime); aq.Add(() => { SceneManager.LoadScene(nextScene); }); aq.Run(); }
public override void Update(GameTime gameTime) { var template = ScriptingEngine.Engine.Templates[templateid]; var targetName = templateid + "|" + Counter++; var sprite = CreateSprite(targetName, template.Attribute("sprite").Value); var createTarget = Source as DrawableGameObject; if (createTarget != null) createTarget.Add(sprite); var targetActions = new ActionQueue(); foreach (var action in template.Elements()) { targetActions.Add(ScriptingEngine.Engine.Provider.ProcessTemplate(action, targetName)); } ScriptingEngine.Add(targetName, sprite, targetActions); CollisionEngine.Add(sprite); Finished = true; }
public void Attack(LbCard target) { ActionQueue.Add(new AttackAction(this, target)); }
public static void RunAfterTick(Action a) { delayedActions.Add(a, RunTime); }
void ValidateClient(Connection newConn, string data) { try { if (State == ServerState.GameStarted) { Log.Write("server", "Rejected connection from {0}; game is already started.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "The game has already started"); DropClient(newConn); return; } var handshake = HandshakeResponse.Deserialize(data); if (!string.IsNullOrEmpty(Settings.Password) && handshake.Password != Settings.Password) { var message = string.IsNullOrEmpty(handshake.Password) ? "Server requires a password" : "Incorrect password"; SendOrderTo(newConn, "AuthenticationError", message); DropClient(newConn); return; } var ipAddress = ((IPEndPoint)newConn.Socket.RemoteEndPoint).Address; var client = new Session.Client { Name = OpenRA.Settings.SanitizedPlayerName(handshake.Client.Name), IPAddress = ipAddress.ToString(), AnonymizedIPAddress = Type != ServerType.Local && Settings.ShareAnonymizedIPs ? Session.AnonymizeIP(ipAddress) : null, Location = GeoIP.LookupCountry(ipAddress), Index = newConn.PlayerIndex, PreferredColor = handshake.Client.PreferredColor, Color = handshake.Client.Color, Faction = "Random", SpawnPoint = 0, Team = 0, State = Session.ClientState.Invalid, }; if (ModData.Manifest.Id != handshake.Mod) { Log.Write("server", "Rejected connection from {0}; mods do not match.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server is running an incompatible mod"); DropClient(newConn); return; } if (ModData.Manifest.Metadata.Version != handshake.Version) { Log.Write("server", "Rejected connection from {0}; Not running the same version.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server is running an incompatible version"); DropClient(newConn); return; } if (handshake.OrdersProtocol != ProtocolVersion.Orders) { Log.Write("server", "Rejected connection from {0}; incompatible Orders protocol version {1}.", newConn.Socket.RemoteEndPoint, handshake.OrdersProtocol); SendOrderTo(newConn, "ServerError", "Server is running an incompatible protocol"); DropClient(newConn); return; } // Check if IP is banned var bans = Settings.Ban.Union(TempBans); if (bans.Contains(client.IPAddress)) { Log.Write("server", "Rejected connection from {0}; Banned.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "You have been {0} from the server".F(Settings.Ban.Contains(client.IPAddress) ? "banned" : "temporarily banned")); DropClient(newConn); return; } Action completeConnection = () => { lock (LobbyInfo) { client.Slot = LobbyInfo.FirstEmptySlot(); client.IsAdmin = !LobbyInfo.Clients.Any(c1 => c1.IsAdmin); if (client.IsObserver && !LobbyInfo.GlobalSettings.AllowSpectators) { SendOrderTo(newConn, "ServerError", "The game is full"); DropClient(newConn); return; } if (client.Slot != null) { SyncClientToPlayerReference(client, Map.Players.Players[client.Slot]); } else { client.Color = Color.White; } // Promote connection to a valid client PreConns.Remove(newConn); Conns.Add(newConn); LobbyInfo.Clients.Add(client); newConn.Validated = true; var clientPing = new Session.ClientPing { Index = client.Index }; LobbyInfo.ClientPings.Add(clientPing); Log.Write("server", "Client {0}: Accepted connection from {1}.", newConn.PlayerIndex, newConn.Socket.RemoteEndPoint); if (client.Fingerprint != null) { Log.Write("server", "Client {0}: Player fingerprint is {1}.", newConn.PlayerIndex, client.Fingerprint); } foreach (var t in serverTraits.WithInterface <IClientJoined>()) { t.ClientJoined(this, newConn); } SyncLobbyInfo(); Log.Write("server", "{0} ({1}) has joined the game.", client.Name, newConn.Socket.RemoteEndPoint); // Report to all other players SendMessage("{0} has joined the game.".F(client.Name), newConn); // Send initial ping SendOrderTo(newConn, "Ping", Game.RunTime.ToString(CultureInfo.InvariantCulture)); if (Type == ServerType.Dedicated) { var motdFile = Platform.ResolvePath(Platform.SupportDirPrefix, "motd.txt"); if (!File.Exists(motdFile)) { File.WriteAllText(motdFile, "Welcome, have fun and good luck!"); } var motd = File.ReadAllText(motdFile); if (!string.IsNullOrEmpty(motd)) { SendOrderTo(newConn, "Message", motd); } } if (Map.DefinesUnsafeCustomRules) { SendOrderTo(newConn, "Message", "This map contains custom rules. Game experience may change."); } if (!LobbyInfo.GlobalSettings.EnableSingleplayer) { SendOrderTo(newConn, "Message", TwoHumansRequiredText); } else if (Map.Players.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots)) { SendOrderTo(newConn, "Message", "Bots have been disabled on this map."); } } }; if (Type == ServerType.Local) { // Local servers can only be joined by the local client, so we can trust their identity without validation client.Fingerprint = handshake.Fingerprint; completeConnection(); } else if (!string.IsNullOrEmpty(handshake.Fingerprint) && !string.IsNullOrEmpty(handshake.AuthSignature)) { waitingForAuthenticationCallback++; Action <DownloadDataCompletedEventArgs> onQueryComplete = i => { PlayerProfile profile = null; if (i.Error == null) { try { var yaml = MiniYaml.FromString(Encoding.UTF8.GetString(i.Result)).First(); if (yaml.Key == "Player") { profile = FieldLoader.Load <PlayerProfile>(yaml.Value); var publicKey = Encoding.ASCII.GetString(Convert.FromBase64String(profile.PublicKey)); var parameters = CryptoUtil.DecodePEMPublicKey(publicKey); if (!profile.KeyRevoked && CryptoUtil.VerifySignature(parameters, newConn.AuthToken, handshake.AuthSignature)) { client.Fingerprint = handshake.Fingerprint; Log.Write("server", "{0} authenticated as {1} (UID {2})", newConn.Socket.RemoteEndPoint, profile.ProfileName, profile.ProfileID); } else if (profile.KeyRevoked) { profile = null; Log.Write("server", "{0} failed to authenticate as {1} (key revoked)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); } else { profile = null; Log.Write("server", "{0} failed to authenticate as {1} (signature verification failed)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); } } else { Log.Write("server", "{0} failed to authenticate as {1} (invalid server response: `{2}` is not `Player`)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint, yaml.Key); } } catch (Exception ex) { Log.Write("server", "{0} failed to authenticate as {1} (exception occurred)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); Log.Write("server", ex.ToString()); } } else { Log.Write("server", "{0} failed to authenticate as {1} (server error: `{2}`)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint, i.Error); } delayedActions.Add(() => { var notAuthenticated = Type == ServerType.Dedicated && profile == null && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Any()); var blacklisted = Type == ServerType.Dedicated && profile != null && Settings.ProfileIDBlacklist.Contains(profile.ProfileID); var notWhitelisted = Type == ServerType.Dedicated && Settings.ProfileIDWhitelist.Any() && (profile == null || !Settings.ProfileIDWhitelist.Contains(profile.ProfileID)); if (notAuthenticated) { Log.Write("server", "Rejected connection from {0}; Not authenticated.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server requires players to have an OpenRA forum account"); DropClient(newConn); } else if (blacklisted || notWhitelisted) { if (blacklisted) { Log.Write("server", "Rejected connection from {0}; In server blacklist.", newConn.Socket.RemoteEndPoint); } else { Log.Write("server", "Rejected connection from {0}; Not in server whitelist.", newConn.Socket.RemoteEndPoint); } SendOrderTo(newConn, "ServerError", "You do not have permission to join this server"); DropClient(newConn); } else { completeConnection(); } waitingForAuthenticationCallback--; }, 0); }; new Download(playerDatabase.Profile + handshake.Fingerprint, _ => { }, onQueryComplete); } else { if (Type == ServerType.Dedicated && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Any())) { Log.Write("server", "Rejected connection from {0}; Not authenticated.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server requires players to have an OpenRA forum account"); DropClient(newConn); } else { completeConnection(); } } } catch (Exception ex) { Log.Write("server", "Dropping connection {0} because an error occurred:", newConn.Socket.RemoteEndPoint); Log.Write("server", ex.ToString()); DropClient(newConn); } }
public void Attack(LbPlayer target) { ActionQueue.Add(new AttackAction(this, target.HeroCard)); }
private void OnHorizontalMove(int x) { actionQueue.Add(new MoveAction(new Vector2(x, 0))); }
public static void EndGame() { ActionQueue.Add(new EndGameAction()); }
public static void EndTurn() { ActionQueue.Add(new EndTurnAction()); }