public VirtualCurrencyPack[] GetCurrencyPacks() { VirtualCurrencyPack[] currencyPacks = new VirtualCurrencyPack[Map_VirtualCurrencyPacks.Count]; Map_VirtualCurrencyPacks.Values.CopyTo(currencyPacks, 0); return(currencyPacks); }
public void BuyCurrencyPack(VirtualCurrencyPack virtualCurrency) { Debug.Log("SOOMLA/UNITY wants to buy: " + virtualCurrency.Name); try { StoreInventory.BuyItem(virtualCurrency.ItemId); } catch (Exception e) { Debug.LogError("SOOMLA/UNITY " + e.Message); } }
private void processCurrencyPack(Dictionary <string, string> atts) { string name = atts["name"]; VirtualCurrencyPack currencyPack = new VirtualCurrencyPack(name, atts["desc"], atts["localID"], Convert.ToInt32(atts["amount"]), atts["currencyID"], new PurchaseWithMarket(atts["cloudID"], Convert.ToDouble(atts["cost"])) ); currencyPack.imageIconPath = atts["spriteIcon"]; ourIAPAssets.Map_VirtualCurrencyPacks[name] = currencyPack; }
public MashinRunAssets() { mashinRunCurrency = new VirtualCurrency("Coin", "the currency of the mashin run game" , "com.mashinran.currency"); moneyCategory = new VirtualCategory("money category" , new List <string>(new string[] { mashinRunCurrency.ItemId })); fiatCar = new EquippableVG (EquippableVG.EquippingModel.GLOBAL, "fiat" , "Fiat", "com.mashinrun.fiat", new PurchaseWithVirtualItem (mashinRunCurrency.ItemId , 2000)); volksWagenCar = new EquippableVG (EquippableVG.EquippingModel.GLOBAL, "volksWagen" , "Volks wagen", "com.mashinrun.volkswagen", new PurchaseWithVirtualItem (mashinRunCurrency.ItemId , 0)); sportCar = new EquippableVG( EquippableVG.EquippingModel.GLOBAL, "sportcar" , "Sport car", "com.mashinrun.sportcar", new PurchaseWithVirtualItem (mashinRunCurrency.ItemId, 20000)); beetleCar = new EquippableVG( EquippableVG.EquippingModel.GLOBAL, "beetle" , "Beetle car", "com.mashinrun.beetle", new PurchaseWithVirtualItem (mashinRunCurrency.ItemId, 8000)); twentyThousandCoinsPack = new VirtualCurrencyPack ("Fifty ThousandCoins", "Fifty thousand coins", "twenty_thousand_coins", 20000 , mashinRunCurrency.ItemId, new PurchaseWithMarket (TWENTY_THOUSAND_COINS_PACK_ITEM_ID, 20000)); fiftyThousandCoinsPack = new VirtualCurrencyPack ("Fifty ThousandCoins", "Fifty thousand coins", "fifty_thousand_coins", 50000 , mashinRunCurrency.ItemId, new PurchaseWithMarket (FIFTY_THOUSAND_COINS_PACK_ITEM_ID, 50000)); tenThousandCoinsPack = new VirtualCurrencyPack("Ten ThousandCoins", "Ten thousand coins", "ten_thousand_coins" , 10000 , mashinRunCurrency.ItemId, new PurchaseWithMarket ("com.mashinran.ten_thousand_coins", 10000)); }
Item ParseToItem(VirtualCurrencyPack cp, ItemType type) { // Create a new item object Item new_item = new Item(); // retrieve the id, name and description new_item.itemId = cp.ItemId; new_item.name = cp.Name; new_item.description = cp.Description; // place the sprite of the item new_item.icon = (Texture2D)Resources.Load(cp.ItemId); // retrieve the currency type and price if (cp.PurchaseType is PurchaseWithVirtualItem && ((PurchaseWithVirtualItem)cp.PurchaseType).TargetItemId == CrapTrapAssets.NORMAL_TOILET_PAPER_ID) { new_item.currency = CurrencyType.NTP; new_item.price = ((PurchaseWithVirtualItem)cp.PurchaseType).Amount; } else if (cp.PurchaseType is PurchaseWithVirtualItem && ((PurchaseWithVirtualItem)cp.PurchaseType).TargetItemId == CrapTrapAssets.GOLDEN_TOILET_PAPER_ID) { new_item.currency = CurrencyType.GTP; new_item.price = ((PurchaseWithVirtualItem)cp.PurchaseType).Amount; } else if (cp.PurchaseType is PurchaseWithMarket) { new_item.currency = CurrencyType.Dollar; new_item.dollarPrice = ((PurchaseWithMarket)cp.PurchaseType).MarketItem.Price; } // set the type new_item.type = type; return(new_item); }
// Use this for initialization private void Start() { switch (this.ItemPack) { case ItemPackType.Token75Pack: this.VirtualCurrencyPack = GnomeStoreAssets.TokenPack75; break; case ItemPackType.Token250Pack: this.VirtualCurrencyPack = GnomeStoreAssets.TokenPack250; break; case ItemPackType.Token500Pack: this.VirtualCurrencyPack = GnomeStoreAssets.TokenPack500; break; default: throw new ArgumentOutOfRangeException(); } this.ItemId = this.VirtualCurrencyPack.ItemId; this.Description.text = this.VirtualCurrencyPack.Description; this.Price.text = "$" + ((PurchaseWithMarket)this.VirtualCurrencyPack.PurchaseType).MarketItem.Price.ToString("F2"); UIPanel uiPanel = NGUITools.FindInParents <UIPanel>(this.gameObject); Vector2 viewSize = uiPanel.GetViewSize(); int buttonWidth = (int)viewSize.x - this.TrimSize; UIWidget uiWidget = this.GetComponent <UIWidget>(); if (uiWidget != null) { uiWidget.SetDimensions(buttonWidth, uiWidget.height); } }
private static void fromJSONObject(JSONObject storeJSON) { VirtualItems = new Dictionary<string, VirtualItem> (); PurchasableItems = new Dictionary<string, PurchasableVirtualItem> (); GoodsCategories = new Dictionary<string, VirtualCategory> (); GoodsUpgrades = new Dictionary<string, List<UpgradeVG>> (); CurrencyPacks = new List<VirtualCurrencyPack> (); Goods = new List<VirtualGood> (); Categories = new List<VirtualCategory> (); Currencies = new List<VirtualCurrency> (); if (storeJSON.HasField (StoreJSONConsts.STORE_CURRENCIES)) { List<JSONObject> objs = storeJSON [StoreJSONConsts.STORE_CURRENCIES].list; foreach (JSONObject o in objs) { VirtualCurrency c = new VirtualCurrency (o); Currencies.Add (c); } } if (storeJSON.HasField (StoreJSONConsts.STORE_CURRENCYPACKS)) { List<JSONObject> objs = storeJSON [StoreJSONConsts.STORE_CURRENCYPACKS].list; foreach (JSONObject o in objs) { VirtualCurrencyPack c = new VirtualCurrencyPack (o); CurrencyPacks.Add (c); } } if (storeJSON.HasField (StoreJSONConsts.STORE_GOODS)) { JSONObject goods = storeJSON [StoreJSONConsts.STORE_GOODS]; if (goods.HasField (StoreJSONConsts.STORE_GOODS_SU)) { List<JSONObject> suGoods = goods [StoreJSONConsts.STORE_GOODS_SU].list; foreach (JSONObject o in suGoods) { var c = new SingleUseVG (o); Goods.Add (c); } } if (goods.HasField (StoreJSONConsts.STORE_GOODS_LT)) { List<JSONObject> ltGoods = goods [StoreJSONConsts.STORE_GOODS_LT].list; foreach (JSONObject o in ltGoods) { LifetimeVG c = new LifetimeVG (o); Goods.Add (c); } } if (goods.HasField (StoreJSONConsts.STORE_GOODS_EQ)) { List<JSONObject> eqGoods = goods [StoreJSONConsts.STORE_GOODS_EQ].list; foreach (JSONObject o in eqGoods) { EquippableVG c = new EquippableVG (o); Goods.Add (c); } } if (goods.HasField (StoreJSONConsts.STORE_GOODS_PA)) { List<JSONObject> paGoods = goods [StoreJSONConsts.STORE_GOODS_PA].list; foreach (JSONObject o in paGoods) { SingleUsePackVG c = new SingleUsePackVG (o); Goods.Add (c); } } if (goods.HasField (StoreJSONConsts.STORE_GOODS_UP)) { List<JSONObject> upGoods = goods [StoreJSONConsts.STORE_GOODS_UP].list; foreach (JSONObject o in upGoods) { UpgradeVG c = new UpgradeVG (o); Goods.Add (c); } } } if (storeJSON.HasField(StoreJSONConsts.STORE_CATEGORIES)) { List<JSONObject> categories = storeJSON[StoreJSONConsts.STORE_CATEGORIES].list; foreach (JSONObject o in categories){ VirtualCategory category = new VirtualCategory(o); Categories.Add(category); } } updateAggregatedLists (); }
public void Prepare(int version, String JsonStoreAssets) { try { mVersion = version; JObject JObject = JObject.Parse(JsonStoreAssets); JArray virtualCurrencies = JObject.Value <JArray>(StoreJSONConsts.STORE_CURRENCIES); mVirtualCurrency = new VirtualCurrency[virtualCurrencies.Count]; for (int i = 0; i < virtualCurrencies.Count; i++) { JObject o = virtualCurrencies.Value <JObject>(i); VirtualCurrency c = new VirtualCurrency(o); mVirtualCurrency[i] = c; } JArray currencyPacks = JObject.Value <JArray>(StoreJSONConsts.STORE_CURRENCYPACKS); mVirtualCurrencyPack = new VirtualCurrencyPack[currencyPacks.Count]; for (int i = 0; i < currencyPacks.Count; i++) { JObject o = currencyPacks.Value <JObject>(i); VirtualCurrencyPack pack = new VirtualCurrencyPack(o); mVirtualCurrencyPack[i] = pack; } // The order in which VirtualGoods are created matters! // For example: VGU and VGP depend on other VGs JObject virtualGoods = JObject.Value <JObject>(StoreJSONConsts.STORE_GOODS); JArray suGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_SU); JArray ltGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_LT); JArray eqGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_EQ); JArray upGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_UP); JArray paGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_PA); List <VirtualGood> goods = new List <VirtualGood>(); for (int i = 0; i < suGoods.Count; i++) { JObject o = suGoods.Value <JObject>(i); SingleUseVG g = new SingleUseVG(o); goods.Add(g); } for (int i = 0; i < ltGoods.Count; i++) { JObject o = ltGoods.Value <JObject>(i); LifetimeVG g = new LifetimeVG(o); goods.Add(g); } for (int i = 0; i < eqGoods.Count; i++) { JObject o = eqGoods.Value <JObject>(i); EquippableVG g = new EquippableVG(o); goods.Add(g); } for (int i = 0; i < paGoods.Count; i++) { JObject o = paGoods.Value <JObject>(i); SingleUsePackVG g = new SingleUsePackVG(o); goods.Add(g); } for (int i = 0; i < upGoods.Count; i++) { JObject o = upGoods.Value <JObject>(i); UpgradeVG g = new UpgradeVG(o); goods.Add(g); } mVirtualGood = new VirtualGood[goods.Count]; for (int i = 0; i < goods.Count; i++) { mVirtualGood[i] = goods[i]; } // categories depend on virtual goods. That's why the have to be initialized after! JArray virtualCategories = JObject.Value <JArray>(StoreJSONConsts.STORE_CATEGORIES); mVirtualCategory = new VirtualCategory[virtualCategories.Count]; for (int i = 0; i < virtualCategories.Count; i++) { JObject o = virtualCategories.Value <JObject>(i); VirtualCategory category = new VirtualCategory(o); mVirtualCategory[i] = category; } JArray nonConsumables = JObject.Value <JArray>(StoreJSONConsts.STORE_NONCONSUMABLES); mNonConsumableItem = new NonConsumableItem[nonConsumables.Count]; for (int i = 0; i < nonConsumables.Count; i++) { JObject o = nonConsumables.Value <JObject>(i); NonConsumableItem non = new NonConsumableItem(o); mNonConsumableItem[i] = non; } } catch (Exception ex) { SoomlaUtils.LogError(TAG, "An error occurred while trying to prepare storeAssets" + ex.Message); } }
/** * Replaces an old virtual item with a new one by doing the following: * 1. Determines the type of the given virtual item. * 2. Looks for the given virtual item in the relevant list, according to its type. * 3. If found, removes it. * 4. Adds the given virtual item. * * @param virtualItem the virtual item that replaces the old one if exists. */ public static void replaceVirtualItem(VirtualItem virtualItem) { mVirtualItems.Add(virtualItem.getItemId(), virtualItem); if (virtualItem is VirtualCurrency) { for (int i = 0; i < mCurrencies.Count; i++) { if (mCurrencies[i].getItemId() == virtualItem.getItemId()) { mCurrencies.RemoveAt(i); break; } } mCurrencies.Add((VirtualCurrency)virtualItem); } if (virtualItem is VirtualCurrencyPack) { VirtualCurrencyPack vcp = (VirtualCurrencyPack)virtualItem; PurchaseType purchaseType = vcp.GetPurchaseType(); if (purchaseType is PurchaseWithMarket) { mPurchasableItems.Add(((PurchaseWithMarket)purchaseType).getMarketItem() .getProductId(), vcp); } for (int i = 0; i < mCurrencyPacks.Count; i++) { if (mCurrencyPacks[i].getItemId() == vcp.getItemId()) { mCurrencyPacks.RemoveAt(i); break; } } mCurrencyPacks.Add(vcp); } if (virtualItem is VirtualGood) { VirtualGood vg = (VirtualGood)virtualItem; if (vg is UpgradeVG) { List <UpgradeVG> upgrades = mGoodsUpgrades[((UpgradeVG)vg).getGoodItemId()]; if (upgrades == null) { upgrades = new List <UpgradeVG>(); mGoodsUpgrades.Add(((UpgradeVG)vg).getGoodItemId(), upgrades); } upgrades.Add((UpgradeVG)vg); } PurchaseType purchaseType = vg.GetPurchaseType(); if (purchaseType is PurchaseWithMarket) { mPurchasableItems.Add(((PurchaseWithMarket)purchaseType).getMarketItem() .getProductId(), vg); } for (int i = 0; i < mGoods.Count; i++) { if (mGoods[i].getItemId() == vg.getItemId()) { mGoods.RemoveAt(i); break; } } mGoods.Add(vg); } /* * if (virtualItem is NonConsumableItem) { * NonConsumableItem non = (NonConsumableItem) virtualItem; * * PurchaseType purchaseType = non.GetPurchaseType(); * if (purchaseType is PurchaseWithMarket) { * mPurchasableItems.Add(((PurchaseWithMarket) purchaseType).getMarketItem() * .getProductId(), non); * } * * for(int i=0; i<mNonConsumables.Count; i++) { * if (mNonConsumables[i].getItemId() == non.getItemId()) { * mNonConsumables.RemoveAt(i); * break; * } * } * mNonConsumables.Add(non); * }*/ }
private void buildShopLine(VirtualItem item) { StackPanel stackP = new StackPanel(); stackP.Orientation = System.Windows.Controls.Orientation.Horizontal; stackP.Margin = new Thickness(0, 15, 0, 0); StackPanel buttonStack = new StackPanel(); buttonStack.Orientation = System.Windows.Controls.Orientation.Vertical; StackPanel textStack = new StackPanel(); textStack.Orientation = System.Windows.Controls.Orientation.Vertical; stackP.Children.Add(buttonStack); stackP.Children.Add(textStack); Button buy = new Button(); buy.Margin = new Thickness(0, 0, 10, 0); buy.Click += buyItem; buy.Content = "buy"; buy.CommandParameter = item.getItemId(); buy.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; buy.VerticalAlignment = System.Windows.VerticalAlignment.Center; buttonStack.Children.Add(buy); if (item is EquippableVG) { Button equip = new Button(); equip.Name = item.getItemId() + "equip"; equip.Margin = new Thickness(0, 0, 10, 0); equip.CommandParameter = item.getItemId(); equip.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; equip.VerticalAlignment = System.Windows.VerticalAlignment.Center; EquippableVG evg = (EquippableVG)item; if (StoreInventory.isVirtualGoodEquipped(item.getItemId())) { equip.Content = "unequip"; equip.Click += unequipItem; } else { equip.Content = "equip"; equip.Click += equipItem; } buttonStack.Children.Add(equip); } TextBlock balance = new TextBlock(); balance.VerticalAlignment = System.Windows.VerticalAlignment.Center; balance.Margin = new Thickness(0, 0, 10, 0); if (!(item is VirtualCurrencyPack) && !(item is NonConsumableItem)) { balance.Text = "balance: " + StoreInventory.getVirtualItemBalance(item.getItemId()).ToString(); } balance.Name = item.getItemId() + "balance"; textStack.Children.Add(balance); TextBlock name = new TextBlock(); name.Margin = new Thickness(0, 0, 10, 0); name.VerticalAlignment = System.Windows.VerticalAlignment.Center; name.Text = "id: " + item.getItemId(); textStack.Children.Add(name); TextBlock price = new TextBlock(); price.Margin = new Thickness(0, 0, 10, 0); price.VerticalAlignment = System.Windows.VerticalAlignment.Center; TextBlock currency = new TextBlock(); currency.Margin = new Thickness(0, 0, 10, 0); currency.VerticalAlignment = System.Windows.VerticalAlignment.Center; if (item is PurchasableVirtualItem) { PurchasableVirtualItem pvi = (PurchasableVirtualItem)item; if (pvi.GetPurchaseType() is PurchaseWithVirtualItem) { PurchaseWithVirtualItem purchaseType = (PurchaseWithVirtualItem)pvi.GetPurchaseType(); price.Text = "price: " + purchaseType.getAmount().ToString(); currency.Text = "currency: " + purchaseType.getTargetItemId(); } if (pvi.GetPurchaseType() is PurchaseWithMarket) { PurchaseWithMarket purchaseType = (PurchaseWithMarket)pvi.GetPurchaseType(); price.Text = "price: " + purchaseType.getMarketItem().getMarketPrice(); } textStack.Children.Add(price); textStack.Children.Add(currency); } if (item is VirtualCurrencyPack) { VirtualCurrencyPack vcp = (VirtualCurrencyPack)item; TextBlock currencyId = new TextBlock(); currencyId.Text = "give currency: " + vcp.getCurrencyItemId().ToString(); TextBlock currencyAmount = new TextBlock(); currencyAmount.Text = "give amount: " + vcp.getCurrencyAmount().ToString(); textStack.Children.Add(currencyId); textStack.Children.Add(currencyAmount); } MainStackPanel.Children.Add(stackP); }
/** Private functions **/ /** * Transforms given JObject to StoreInfo * * @param JObject * @throws JSONException */ private static void fromJObject(JObject JObject) { mVirtualItems = new Dictionary <String, VirtualItem>(); mPurchasableItems = new Dictionary <String, PurchasableVirtualItem>(); mGoodsCategories = new Dictionary <String, VirtualCategory>(); mGoodsUpgrades = new Dictionary <String, List <UpgradeVG> >(); mCurrencyPacks = new List <VirtualCurrencyPack>(); mGoods = new List <VirtualGood>(); mCategories = new List <VirtualCategory>(); mCurrencies = new List <VirtualCurrency>(); mNonConsumables = new List <NonConsumableItem>(); JToken value; if (JObject.TryGetValue(StoreJSONConsts.STORE_CURRENCIES, out value)) { JArray virtualCurrencies = JObject.Value <JArray>(StoreJSONConsts.STORE_CURRENCIES); for (int i = 0; i < virtualCurrencies.Count; i++) { JObject o = virtualCurrencies.Value <JObject>(i); VirtualCurrency c = new VirtualCurrency(o); mCurrencies.Add(c); mVirtualItems.Add(c.getItemId(), c); } } if (JObject.TryGetValue(StoreJSONConsts.STORE_CURRENCYPACKS, out value)) { JArray currencyPacks = JObject.Value <JArray>(StoreJSONConsts.STORE_CURRENCYPACKS); for (int i = 0; i < currencyPacks.Count; i++) { JObject o = currencyPacks.Value <JObject>(i); VirtualCurrencyPack pack = new VirtualCurrencyPack(o); mCurrencyPacks.Add(pack); mVirtualItems.Add(pack.getItemId(), pack); PurchaseType purchaseType = pack.GetPurchaseType(); if (purchaseType is PurchaseWithMarket) { mPurchasableItems.Add(((PurchaseWithMarket)purchaseType) .getMarketItem().getProductId(), pack); } } } // The order in which VirtualGoods are created matters! // For example: VGU and VGP depend on other VGs if (JObject.TryGetValue(StoreJSONConsts.STORE_GOODS, out value)) { JObject virtualGoods = JObject.Value <JObject>(StoreJSONConsts.STORE_GOODS); JToken valueVg; if (virtualGoods.TryGetValue(StoreJSONConsts.STORE_GOODS_SU, out valueVg)) { JArray suGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_SU); for (int i = 0; i < suGoods.Count; i++) { JObject o = suGoods.Value <JObject>(i); SingleUseVG g = new SingleUseVG(o); addVG(g); } } if (virtualGoods.TryGetValue(StoreJSONConsts.STORE_GOODS_LT, out valueVg)) { JArray ltGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_LT); for (int i = 0; i < ltGoods.Count; i++) { JObject o = ltGoods.Value <JObject>(i); LifetimeVG g = new LifetimeVG(o); addVG(g); } } if (virtualGoods.TryGetValue(StoreJSONConsts.STORE_GOODS_EQ, out valueVg)) { JArray eqGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_EQ); for (int i = 0; i < eqGoods.Count; i++) { JObject o = eqGoods.Value <JObject>(i); EquippableVG g = new EquippableVG(o); addVG(g); } } if (virtualGoods.TryGetValue(StoreJSONConsts.STORE_GOODS_PA, out valueVg)) { JArray paGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_PA); for (int i = 0; i < paGoods.Count; i++) { JObject o = paGoods.Value <JObject>(i); SingleUsePackVG g = new SingleUsePackVG(o); addVG(g); } } if (virtualGoods.TryGetValue(StoreJSONConsts.STORE_GOODS_UP, out valueVg)) { JArray upGoods = virtualGoods.Value <JArray>(StoreJSONConsts.STORE_GOODS_UP); for (int i = 0; i < upGoods.Count; i++) { JObject o = upGoods.Value <JObject>(i); UpgradeVG g = new UpgradeVG(o); addVG(g); List <UpgradeVG> upgrades = mGoodsUpgrades[g.getGoodItemId()]; if (upgrades == null) { upgrades = new List <UpgradeVG>(); mGoodsUpgrades.Add(g.getGoodItemId(), upgrades); } upgrades.Add(g); } } } // Categories depend on virtual goods. That's why the have to be initialized after! if (JObject.TryGetValue(StoreJSONConsts.STORE_CATEGORIES, out value)) { JArray virtualCategories = JObject.Value <JArray>(StoreJSONConsts.STORE_CATEGORIES); for (int i = 0; i < virtualCategories.Count; i++) { JObject o = virtualCategories.Value <JObject>(i); VirtualCategory category = new VirtualCategory(o); mCategories.Add(category); foreach (String goodItemId in category.getGoodsItemIds()) { mGoodsCategories.Add(goodItemId, category); } } } if (JObject.TryGetValue(StoreJSONConsts.STORE_NONCONSUMABLES, out value)) { JArray nonConsumables = JObject.Value <JArray>(StoreJSONConsts.STORE_NONCONSUMABLES); for (int i = 0; i < nonConsumables.Count; i++) { JObject o = nonConsumables.Value <JObject>(i); NonConsumableItem non = new NonConsumableItem(o); mNonConsumables.Add(non); mVirtualItems.Add(non.getItemId(), non); PurchaseType purchaseType = non.GetPurchaseType(); if (purchaseType is PurchaseWithMarket) { mPurchasableItems.Add(((PurchaseWithMarket)purchaseType) .getMarketItem().getProductId(), non); } } } }