| //--------------------------------------------------------  | 
| //    [Author]:           第二世界  | 
| //    [  Date ]:           Tuesday, September 12, 2017  | 
| //--------------------------------------------------------  | 
|   | 
| using System;  | 
| using System.Collections;  | 
| using System.Collections.Generic;  | 
| using UnityEngine;  | 
| using UnityEngine.UI;  | 
|   | 
| using vnxbqy.UI;  | 
|   | 
| namespace vnxbqy.UI  | 
| {  | 
|     public class NormalDungeonEntranceWin : Window, SecondWindowInterface  | 
|     {  | 
|         [SerializeField] Image m_EntranceBG;  | 
|   | 
|         [Header("BaseInfo")]  | 
|         [SerializeField] RawImage m_BossPortrayal;  | 
|         [SerializeField] DungeonBreifInfo m_BreifInfo;  | 
|   | 
|         [Header("EnterCD")]  | 
|         [SerializeField]  | 
|         DungeonEnterInfo m_EnterCdContainer;  | 
|   | 
|         [Header("Sweep")]  | 
|         [SerializeField]  | 
|         Text m_SweepLevelNeed;  | 
|         [SerializeField] ItemBehaviour m_SweepContainer;  | 
|         [SerializeField] Text m_SweepCostCount;  | 
|   | 
|         [Header("DungeonTicket")]  | 
|         [SerializeField]  | 
|         Transform m_TicketContainer;  | 
|         [SerializeField]  | 
|         ItemBehaviour m_DungeonTicketItem;  | 
|   | 
|         [Header("Button")]  | 
|         [SerializeField]  | 
|         ButtonEx m_Sweep;  | 
|         [SerializeField] RectTransform m_ContainerBtns;  | 
|         [SerializeField] ButtonEx m_GroupStart;  | 
|         [SerializeField] ButtonEx m_SingleStart;  | 
|         [SerializeField] ButtonEx m_AutoGroupStart;  | 
|         [SerializeField] ButtonEx m_Group;  | 
|   | 
|         [SerializeField] RectTransform m_ContainerGroup;  | 
|   | 
|         [SerializeField] RectTransform m_FairyLandTipBehaviour;  | 
|         [SerializeField] Text m_FairyLandTip;  | 
|         [SerializeField] Text m_WhyjEnterRule;//娲皇遗迹  | 
|         [SerializeField] Text WhyjEnterFloor;//娲皇遗迹  | 
|         [SerializeField] Button m_RuletBtn;//规则说明按钮  | 
|   | 
|         DungeonModel model { get { return ModelCenter.Instance.GetModel<DungeonModel>(); } }  | 
|         TeamModel teamModel { get { return ModelCenter.Instance.GetModel<TeamModel>(); } }  | 
|         PackModel playerPack { get { return ModelCenter.Instance.GetModel<PackModel>(); } }  | 
|         DungeonNuwaModel dungeonNuwaModel { get { return ModelCenter.Instance.GetModel<DungeonNuwaModel>(); } }  | 
|   | 
|         public Button close { get; set; }  | 
|         Text m_DungeonTitle;  | 
|   | 
|         #region Built-in  | 
|         protected override void BindController()  | 
|         {  | 
|             if (this is SecondWindowInterface)  | 
|             {  | 
|                 var frame = this.GetComponentInChildren<SecondFrameLoader>();  | 
|                 frame.Create();  | 
|                 close = frame.GetComponentInChildren<Button>();  | 
|                 m_DungeonTitle = frame.GetComponentInChildren<Text>();  | 
|             }  | 
|         }  | 
|   | 
|         protected override void AddListeners()  | 
|         {  | 
|             m_GroupStart.AddListener(ChallengeDungeonGroup);  | 
|             m_SingleStart.AddListener(ChallengeDungeon);  | 
|             m_AutoGroupStart.AddListener(AutoGroupChallenge);  | 
|             m_Sweep.AddListener(SweepDungeon);  | 
|             m_Group.AddListener(OpenGroup);  | 
|             close.AddListener(CloseClick);  | 
|             m_RuletBtn.AddListener(RuletBtn);  | 
|         }  | 
|   | 
|         protected override void OnPreOpen()  | 
|         {  | 
|             DrawDungeonBaseInfo();  | 
|             DrawSweepInfo();  | 
|             DrawDungeonTicketInfo();  | 
|             DisplayFairyLandTip();  | 
|             m_BreifInfo.SetDungeonInfo(model.currentDungeon);  | 
|   | 
|             if (DungeonNuwaModel.DATAMAPID == model.currentDungeon.mapId)//娲皇遗迹  | 
|             {  | 
|                 m_WhyjEnterRule.SetActive(true);  | 
|                 WhyjEnterFloor.SetActive(true);  | 
|                 m_WhyjEnterRule.text = Language.Get("WhyjEnterRule");  | 
|                 int floor = dungeonNuwaModel.GetChallengeFloor();  | 
|                 WhyjEnterFloor.text = Language.Get("WhyjEnterFloor", floor);  | 
|             }  | 
|             else  | 
|             {  | 
|                 m_WhyjEnterRule.SetActive(false);  | 
|                 WhyjEnterFloor.SetActive(false);  | 
|             }  | 
|   | 
|             if (model.currentDungeon.mapId == DungeonNuwaModel.DATAMAPID)  | 
|             {  | 
|                 m_RuletBtn.SetActive(true);  | 
|             }  | 
|             else  | 
|             {  | 
|                 m_RuletBtn.SetActive(false);  | 
|             }  | 
|         }  | 
|   | 
|         protected override void OnAfterOpen()  | 
|         {  | 
|             playerPack.refreshItemCountEvent += OnPackageItemChange;  | 
|             model.dungeonEnterCoolDownUpdate += DungeonEnterCoolDownUpdate;  | 
|             m_EnterCdContainer.OnCoolDowndComplete += DungeonEnterCoolDownUpdate;  | 
|             PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshInfoEvent;  | 
|             PlayerDatas.Instance.worldLevelUpdateEvent += OnWorldLevelRefresh;  | 
|             FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;  | 
|         }  | 
|   | 
|         protected override void OnPreClose()  | 
|         {  | 
|             playerPack.refreshItemCountEvent -= OnPackageItemChange;  | 
|             model.dungeonEnterCoolDownUpdate -= DungeonEnterCoolDownUpdate;  | 
|             m_EnterCdContainer.OnCoolDowndComplete -= DungeonEnterCoolDownUpdate;  | 
|             PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshInfoEvent;  | 
|             PlayerDatas.Instance.worldLevelUpdateEvent -= OnWorldLevelRefresh;  | 
|             FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;  | 
|         }  | 
|   | 
|         protected override void OnAfterClose()  | 
|         {  | 
|   | 
|         }  | 
|   | 
|         protected override void LateUpdate()  | 
|         {  | 
|             base.LateUpdate();  | 
|         }  | 
|         #endregion  | 
|   | 
|         private void OpenGroup()  | 
|         {  | 
|             var openGroup = m_ContainerGroup.gameObject.activeSelf;  | 
|             m_ContainerGroup.SetActive(!openGroup);  | 
|         }  | 
|   | 
|         private void DungeonEnterCoolDownUpdate()  | 
|         {  | 
|             var dungeonId = model.GetDungeonId(model.currentDungeon);  | 
|             var dungeonConfig = DungeonConfig.Get(dungeonId);  | 
|             bool inCoolDown = model.ContainsDungeonEnter(dungeonConfig.DataMapID) && model.IsEnterCountDown(dungeonConfig.DataMapID);  | 
|             m_EnterCdContainer.SetActive(inCoolDown);  | 
|             m_ContainerBtns.SetActive(!inCoolDown);  | 
|             DisplayFairyLandTip();  | 
|         }  | 
|   | 
|         private void DrawDungeonBaseInfo()  | 
|         {  | 
|             var dungeonId = model.GetDungeonId(model.currentDungeon);  | 
|             var dungeonConfig = DungeonConfig.Get(dungeonId);  | 
|             var dungeonOpenTimeConfig = DungeonOpenTimeConfig.Get(model.currentDungeon.mapId);  | 
|             var fbType = dungeonOpenTimeConfig.FBType;  | 
|             m_GroupStart.SetActive(fbType == 2 || fbType == 3);  | 
|             m_SingleStart.SetActive(fbType == 1 || fbType == 2);  | 
|             m_AutoGroupStart.SetActive(fbType == 2 || fbType == 3);  | 
|   | 
|             m_ContainerGroup.SetActive(false);  | 
|             m_Group.SetActive(fbType == 2 || fbType == 3);  | 
|   | 
|             m_EntranceBG.SetSprite(dungeonOpenTimeConfig.PanelImg);  | 
|   | 
|             m_DungeonTitle.text = dungeonConfig.FBName;  | 
|   | 
|             DungeonEnterCoolDownUpdate();  | 
|   | 
|             m_BossPortrayal.SetActive(true);  | 
|             if (dungeonConfig.BossActorID != null && dungeonConfig.BossActorID.Length > 0)  | 
|             {  | 
|                 if (dungeonConfig.BossActorID[0] == 0)  | 
|                 {  | 
|                     m_BossPortrayal.SetActive(false);  | 
|                 }  | 
|                 else  | 
|                 {  | 
|                     UI3DModelExhibition.Instance.ShowNPC(dungeonConfig.BossActorID[0], Vector3.zero, m_BossPortrayal);  | 
|                 }  | 
|   | 
|             }  | 
|         }  | 
|   | 
|         private void DrawSweepInfo()  | 
|         {  | 
|             var dungeonId = model.GetDungeonId(model.currentDungeon);  | 
|             var dungeonConfig = DungeonConfig.Get(dungeonId);  | 
|   | 
|             var playerLevel = PlayerDatas.Instance.baseData.LV;  | 
|             var sweepLevelLimit = dungeonConfig.SweepLVLimit;  | 
|   | 
|             if (dungeonConfig.SweepLVLimit == 0)  | 
|             {  | 
|                 m_Sweep.SetActive(false);  | 
|                 m_SweepContainer.SetActive(false);  | 
|                 m_SweepLevelNeed.SetActive(false);  | 
|             }  | 
|             else  | 
|             {  | 
|                 m_SweepLevelNeed.SetActive(true);  | 
|                 m_SweepLevelNeed.text = Language.Get("SweepLevelLimit", dungeonConfig.SweepLVLimit);  | 
|                 m_SweepContainer.SetActive(false);  | 
|                 m_Sweep.SetActive(true);  | 
|             }  | 
|             GetWidgt<Transform>("EfficienBtn").SetActive(dungeonConfig.DataMapID == 31080);  | 
|   | 
|             int buffid = 0;  | 
|             var dungeonLiquidModel = ModelCenter.Instance.GetModel<DungeonLiquidModel>();  | 
|             var Buffmodel = ModelCenter.Instance.GetModel<BuffModel>();  | 
|             for (int i = 0; i < dungeonLiquidModel.liquidItems.Count; i++)  | 
|             {  | 
|                 ItemConfig cfg = ItemConfig.Get(dungeonLiquidModel.liquidItems[i]);  | 
|                 if (Buffmodel._BuffDic.ContainsKey(cfg.AddSkill1))  | 
|                 {  | 
|                     buffid = cfg.AddSkill1;  | 
|                     break;  | 
|                 }  | 
|             }  | 
|             GetWidgt<Transform>("Exp").SetActive(buffid == 0);  | 
|         }  | 
|   | 
|         private void DrawDungeonTicketInfo()  | 
|         {  | 
|             var config = DungeonConfig.Get(model.GetDungeonId(model.currentDungeon));  | 
|             if (config == null || config.TicketID == 0)  | 
|             {  | 
|                 m_TicketContainer.SetActive(false);  | 
|             }  | 
|             else  | 
|             {  | 
|                 m_TicketContainer.SetActive(true);  | 
|                 m_DungeonTicketItem.showCount = true;  | 
|                 DungeonRecord record;  | 
|                 int _times = 0;  | 
|                 if (model.TryGetRecord(model.currentDungeon.mapId, out record))  | 
|                 {  | 
|                     _times = record.enterTimes;  | 
|                 }  | 
|                 m_DungeonTicketItem.SetItem(model.GetTicketCost(model.currentDungeon.mapId, model.currentDungeon.lineId));  | 
|             }  | 
|         }  | 
|   | 
|         private void SweepDungeon()  | 
|         {  | 
|             var sweepError = 0;  | 
|             if (TestSweepDungeon(out sweepError))  | 
|             {  | 
|                 model.RequestSweep(model.currentDungeon);  | 
|             }  | 
|             else  | 
|             {  | 
|                 ProcessSweepDungeonError(sweepError);  | 
|             }  | 
|         }  | 
|   | 
|         private void ChallengeDungeon()  | 
|         {  | 
|             switch (model.currentDungeon.mapId)  | 
|             {  | 
|                 case 51010://娲皇遗迹  | 
|                     DungeonRecord record;  | 
|                     model.TryGetRecord(51010, out record);  | 
|                     var entertimes = model.GetEnterTimes(51010);  | 
|                     var totalTimes = model.GetTotalTimes(51010);  | 
|                     if (entertimes >= totalTimes)  | 
|                     {  | 
|                         ProcessEnterDungeonError(4);  | 
|                         return;  | 
|                     }  | 
|   | 
|                     var floor = dungeonNuwaModel.GetChallengeFloor();  | 
|                     model.currentDungeon = new Dungeon(DungeonNuwaModel.DATAMAPID, floor - 1);  | 
|                     break;  | 
|             }  | 
|   | 
|             var error = 0;  | 
|             if (model.TestChallange(model.currentDungeon, out error))  | 
|             {  | 
|                 if (GeneralDefine.dungeonCanUseMoneyIds.Contains(model.currentDungeon.mapId))  | 
|                 {  | 
|                     CheckUseMoneyDungeon(model.currentDungeon);  | 
|                 }  | 
|                 else  | 
|                 {  | 
|                     model.SingleChallenge(model.currentDungeon);  | 
|                 }  | 
|             }  | 
|             else  | 
|             {  | 
|                 if (GeneralDefine.dungeonCanUseMoneyIds.Contains(model.currentDungeon.mapId)  | 
|                     && error == 5)  | 
|                 {  | 
|                     CheckUseMoneyDungeon(model.currentDungeon);  | 
|                 }  | 
|                 else  | 
|                 {  | 
|                     ProcessEnterDungeonError(error);  | 
|                 }  | 
|             }  | 
|         }  | 
|   | 
|         private void CheckUseMoneyDungeon(Dungeon _dungeon)  | 
|         {  | 
|             var mapId = _dungeon.mapId;  | 
|             var mapConfig = MapConfig.Get(mapId);  | 
|   | 
|             if ((MapType)mapConfig.MapFBType == MapType.MultipleFB)  | 
|             {  | 
|                 var teamModel = ModelCenter.Instance.GetModel<TeamModel>();  | 
|                 if (teamModel.myTeam.inTeam)  | 
|                 {  | 
|                     ConfirmCancel.ShowPopConfirm(  | 
|                         Language.Get("Mail101"),  | 
|                         Language.Get("PlayerExitTeamSolo"),  | 
|   | 
|                         (bool _ok) =>  | 
|                         {  | 
|                             if (_ok)  | 
|                             {  | 
|                                 teamModel.RequestExitTeam();  | 
|                                 Clock.AlarmAt(DateTime.Now + new TimeSpan(1 * TimeSpan.TicksPerSecond),  | 
|                                     () =>  | 
|                                     {  | 
|                                         OpenDungeonSuppliesLack(_dungeon);  | 
|                                     }  | 
|                                     );  | 
|                             }  | 
|                         }  | 
|                         );  | 
|   | 
|                     return;  | 
|                 }  | 
|             }  | 
|             OpenDungeonSuppliesLack(_dungeon);  | 
|         }  | 
|   | 
|         void OpenDungeonSuppliesLack(Dungeon _dungeon)  | 
|         {  | 
|             switch (_dungeon.mapId)  | 
|             {  | 
|                 case 31080:  | 
|                     DungeonSuppliesLackWin.lackType = DungeonSuppliesLackWin.LackType.FairyLand;  | 
|                     WindowCenter.Instance.Open<DungeonSuppliesLackWin>();  | 
|                     break;  | 
|                 case 31140:  | 
|                     DungeonSuppliesLackWin.lackType = DungeonSuppliesLackWin.LackType.SingleIceCrystal;  | 
|                     WindowCenter.Instance.Open<DungeonSuppliesLackWin>();  | 
|                     break;  | 
|             }  | 
|         }  | 
|   | 
|         private void AutoGroupChallenge()  | 
|         {  | 
|             var error = 0;  | 
|             if (model.TestChallange(model.currentDungeon, out error))  | 
|             {  | 
|                 teamModel.RequestAutoMatchTeam(new TeamMission(model.currentDungeon.mapId, model.currentDungeon.lineId));  | 
|                 WindowCenter.Instance.Open<TeamFrameWin>(false, 1);  | 
|             }  | 
|             else  | 
|             {  | 
|                 ProcessEnterDungeonError(error);  | 
|             }  | 
|         }  | 
|   | 
|         private void ChallengeDungeonGroup()  | 
|         {  | 
|             var error = 0;  | 
|             if (model.TestChallange(model.currentDungeon, out error))  | 
|             {  | 
|                 model.GroupChallenge(model.currentDungeon);  | 
|             }  | 
|             else  | 
|             {  | 
|                 ProcessEnterDungeonError(error);  | 
|             }  | 
|         }  | 
|   | 
|         private void ProcessEnterDungeonError(int _error)  | 
|         {  | 
|             var dungeonId = model.GetDungeonId(model.currentDungeon);  | 
|             var dungeonConfig = DungeonConfig.Get(dungeonId);  | 
|   | 
|             switch (_error)  | 
|             {  | 
|                 case 1:  | 
|                     SysNotifyMgr.Instance.ShowTip("DungeoninCoolTime");  | 
|                     break;  | 
|                 case 2:  | 
|                     SysNotifyMgr.Instance.ShowTip("DemonJar_Text2");  | 
|                     break;  | 
|                 case 4:  | 
|                     SysNotifyMgr.Instance.ShowTip("GeRen_chenxin_268121", dungeonConfig.MapID);  | 
|                     break;  | 
|                 case 5:  | 
|                     ItemTipUtility.Show(dungeonConfig.TicketID);  | 
|                     break;  | 
|                 case 6:  | 
|                     SysNotifyMgr.Instance.ShowTip("CrossMap10");  | 
|                     break;  | 
|             }  | 
|         }  | 
|   | 
|         private bool TestSweepDungeon(out int _error)  | 
|         {  | 
|             var dungeonId = model.GetDungeonId(model.currentDungeon);  | 
|             var dungeonConfig = DungeonConfig.Get(dungeonId);  | 
|             var playerLevel = PlayerDatas.Instance.baseData.LV;  | 
|             var dungeonGrade = model.GetGrade(model.currentDungeon);  | 
|   | 
|             var dataMapId = model.GetDataMapIdByMapId(PlayerDatas.Instance.baseData.MapID);  | 
|             if (dataMapId == model.currentDungeon.mapId)  | 
|             {  | 
|                 _error = 5;  | 
|                 return false;  | 
|             }  | 
|   | 
|             var sweepGradeLimit = 0;  | 
|   | 
|   | 
|             if (sweepGradeLimit != 0 && dungeonGrade < sweepGradeLimit)  | 
|             {  | 
|                 _error = 1;  | 
|                 return false;  | 
|             }  | 
|   | 
|             //if (dungeonGrade <= 0)  | 
|             //{  | 
|             //    _error = 2;  | 
|             //    return false;  | 
|             //}  | 
|   | 
|             if (playerLevel < dungeonConfig.SweepLVLimit)  | 
|             {  | 
|                 _error = 3;  | 
|                 return false;  | 
|             }  | 
|   | 
|             if (model.IsEnterCountDown(model.currentDungeon.mapId))  | 
|             {  | 
|                 _error = 4;  | 
|                 return false;  | 
|             }  | 
|   | 
|             _error = 0;  | 
|             return true;  | 
|         }  | 
|   | 
|         private void ProcessSweepDungeonError(int _error)  | 
|         {  | 
|             var dungeonId = model.GetDungeonId(model.currentDungeon);  | 
|             var dungeonConfig = DungeonConfig.Get(dungeonId);  | 
|   | 
|             var sweepGradeLimit = 0;  | 
|   | 
|             switch (_error)  | 
|             {  | 
|                 case 1:  | 
|                     SysNotifyMgr.Instance.ShowTip("Unlock_BJMopUp1", sweepGradeLimit);  | 
|                     break;  | 
|                 case 2:  | 
|                     SysNotifyMgr.Instance.ShowTip("Unlock_BJMopUp2", sweepGradeLimit);  | 
|                     break;  | 
|                 case 3:  | 
|                     SysNotifyMgr.Instance.ShowTip("Unlock_BJMopUp3", dungeonConfig.SweepLVLimit);  | 
|                     break;  | 
|                 case 4:  | 
|                     SysNotifyMgr.Instance.ShowTip("DungeoninCoolTime");  | 
|                     break;  | 
|                 case 5:  | 
|                     SysNotifyMgr.Instance.ShowTip("SweepFB_1");  | 
|                     break;  | 
|             }  | 
|         }  | 
|   | 
|           | 
|         private void OnPackageItemChange(PackType _type, int _index, int _itemId)  | 
|         {  | 
|             if (_type != PackType.Item)  | 
|             {  | 
|                 return;  | 
|             }  | 
|   | 
|             if (_itemId == m_SweepContainer.itemId)  | 
|             {  | 
|                 var sweepCost = model.GetSweepCost(model.currentDungeon);  | 
|                 var own = playerPack.GetItemCountByID(PackType.Item, sweepCost.id);  | 
|                 m_SweepCostCount.text = StringUtility.Contact(own, "/", sweepCost.count);  | 
|             }  | 
|   | 
|             if (_itemId == m_DungeonTicketItem.itemId)  | 
|             {  | 
|                 m_DungeonTicketItem.SetItem(model.GetTicketCost(model.currentDungeon.mapId, model.currentDungeon.lineId));  | 
|             }  | 
|   | 
|             if (ModelCenter.Instance.GetModel<DungeonLiquidModel>().liquidItems.Contains(_itemId))  | 
|             {  | 
|                 DrawSweepInfo();  | 
|             }  | 
|         }  | 
|   | 
|         private void PlayerDataRefreshInfoEvent(PlayerDataType refreshType)  | 
|         {  | 
|             if (refreshType == PlayerDataType.LV)  | 
|             {  | 
|                 DisplayFairyLandTip();  | 
|                 DungeonEnterCoolDownUpdate();  | 
|             }  | 
|         }  | 
|   | 
|         private void OnWorldLevelRefresh()  | 
|         {  | 
|             DisplayFairyLandTip();  | 
|         }  | 
|   | 
|         private void OnFuncStateChangeEvent(int id)  | 
|         {  | 
|             if (id == (int)FuncOpenEnum.WorldLv)  | 
|             {  | 
|                 DisplayFairyLandTip();  | 
|             }  | 
|         }  | 
|   | 
|         private void DisplayFairyLandTip()  | 
|         {  | 
|             var dungeonId = model.GetDungeonId(model.currentDungeon);  | 
|             var dungeonConfig = DungeonConfig.Get(dungeonId);  | 
|             bool inCoolDown = model.ContainsDungeonEnter(dungeonConfig.DataMapID) && model.IsEnterCountDown(dungeonConfig.DataMapID);  | 
|             var satisfy = (PlayerDatas.Instance.baseData.LV + GeneralDefine.fairyLandBuffCondition) <= PlayerDatas.Instance.worldLv  | 
|                && dungeonConfig.DataMapID == 31080 && !inCoolDown && FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.WorldLv);  | 
|             m_FairyLandTipBehaviour.SetActive(satisfy);  | 
|             var config = SkillConfig.Get(GeneralDefine.fairyLandBuffId);  | 
|             if (config != null)  | 
|             {  | 
|                 m_FairyLandTip.text = UIHelper.ReplaceNewLine(Language.Get("XjmjAddHarm1",  | 
|                     GeneralDefine.fairyLandBuffCondition, config.EffectValue11 / 10000 + 1));  | 
|             }  | 
|         }  | 
|   | 
|         private void RuletBtn()//规则按钮  | 
|         {  | 
|             if (DungeonNuwaModel.DATAMAPID == model.currentDungeon.mapId)  | 
|             {  | 
|                 WindowCenter.Instance.Open<DungeonNuwaRuleWin>();  | 
|             }  | 
|   | 
|         }  | 
|     }  | 
|   | 
| }  | 
|   | 
|   | 
|   | 
|   |