From 8facb17eb424c6856052af8292d2ed7d93e1ba7b Mon Sep 17 00:00:00 2001 From: SepComet <202308010230@stu.csust.edu.cn> Date: Tue, 24 Feb 2026 21:14:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=A1=B9=E7=9B=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- Assets/GameMain/Configs/ResourceBuilder.xml | 4 +- Assets/GameMain/DataTables/UIForm.txt | 7 +- .../Scripts/Definition/Enum/UIFormId.cs | 2 + .../Scripts/Procedure/ProcedureCombine.cs | 215 +----------------- .../UI/Controller/CombineFormController.cs | 18 +- .../GameMain/Scripts/UI/View/SettingForm.cs | 6 +- Assets/Launcher.unity | 11 +- ProjectSettings/GraphicsSettings.asset | 12 +- ProjectSettings/ProjectSettings.asset | 2 +- 数据表/Sound.txt | 9 - 数据表/UIForm.txt | 7 +- 数据表/UIForm.xlsx | Bin 10336 -> 10411 bytes 13 files changed, 49 insertions(+), 247 deletions(-) delete mode 100644 数据表/Sound.txt diff --git a/.gitignore b/.gitignore index afaaf51..368dc70 100644 --- a/.gitignore +++ b/.gitignore @@ -94,4 +94,5 @@ crashlytics-build.properties /数据表/__pycache__ /Release -/AssetBundles \ No newline at end of file +/AssetBundles +/Android \ No newline at end of file diff --git a/Assets/GameMain/Configs/ResourceBuilder.xml b/Assets/GameMain/Configs/ResourceBuilder.xml index ef44c2c..0787960 100644 --- a/Assets/GameMain/Configs/ResourceBuilder.xml +++ b/Assets/GameMain/Configs/ResourceBuilder.xml @@ -2,8 +2,8 @@ - 1 - 1 + 2 + 33 1 UnityGameFramework.Runtime.DefaultCompressionHelper True diff --git a/Assets/GameMain/DataTables/UIForm.txt b/Assets/GameMain/DataTables/UIForm.txt index c97b02d..54e9bb5 100644 --- a/Assets/GameMain/DataTables/UIForm.txt +++ b/Assets/GameMain/DataTables/UIForm.txt @@ -7,6 +7,7 @@ 101 设置 SettingForm Default False True 102 关于 AboutForm Default False True 103 组装玩法UI CombineForm Default False False - 104 Mask对话UI MaskDialogForm Default False False - 105 Bottom对话UI BottomBoxDialogForm Default False False - 106 Bubble对话UI BubbleDialogForm Default True False + 104 Mask对话UI MaskDialogForm Dialog False False + 105 Bottom对话UI BottomBoxDialogForm Dialog False False + 106 Bubble对话UI BubbleDialogForm Dialog True False + 107 游戏场景覆盖UI MainOverlayForm Overlay False False diff --git a/Assets/GameMain/Scripts/Definition/Enum/UIFormId.cs b/Assets/GameMain/Scripts/Definition/Enum/UIFormId.cs index f3ca7c5..020aef9 100644 --- a/Assets/GameMain/Scripts/Definition/Enum/UIFormId.cs +++ b/Assets/GameMain/Scripts/Definition/Enum/UIFormId.cs @@ -53,5 +53,7 @@ namespace UI /// 气泡剧情对话界面。 /// BubbleDialogForm = 106, + + MainOverlayForm = 107, } } diff --git a/Assets/GameMain/Scripts/Procedure/ProcedureCombine.cs b/Assets/GameMain/Scripts/Procedure/ProcedureCombine.cs index 457322b..b26c271 100644 --- a/Assets/GameMain/Scripts/Procedure/ProcedureCombine.cs +++ b/Assets/GameMain/Scripts/Procedure/ProcedureCombine.cs @@ -20,51 +20,6 @@ namespace Procedure { #region Property - /// - /// 单局超时时间(秒)。 - /// - private const float TimeoutSeconds = 180f; - - /// - /// 结算后重开场景的延迟(秒)。 - /// - private const float RestartDelaySeconds = 2f; - - /// - /// 统一日志前缀。 - /// - private const string LogPrefix = "[GameplayATest]"; - - /// - /// 当前局是否已开始。 - /// - private bool _isStarted = false; - - /// - /// 当前局是否已结束。 - /// - private bool _isFinished = false; - - /// - /// 当前局是否通过。 - /// - private bool _isPassed = false; - - /// - /// 当前局累计耗时(秒)。 - /// - private float _elapsed = 0f; - - /// - /// 结算后的重开倒计时(秒)。 - /// - private float _restartCountdown = 0f; - - /// - /// 当前局开始时的实时时间戳。 - /// - private float _startTimestamp = 0f; - /// /// 拼装玩法组件入口。 /// @@ -85,10 +40,10 @@ namespace Procedure protected override void OnEnter(ProcedureOwner procedureOwner) { base.OnEnter(procedureOwner); - + //InitializeProcedureState(); GameEntry.Dialog.Init(1); - + //GameEntry.Dialog.StartDialog(1001); GameEntry.Dialog.StartDialog(1002); } @@ -98,8 +53,6 @@ namespace Procedure /// protected override void OnLeave(ProcedureOwner procedureOwner, bool isShutdown) { - ShutdownProcedureState(); - base.OnLeave(procedureOwner, isShutdown); } @@ -114,7 +67,6 @@ namespace Procedure if (GameEntry.Dialog.IsInitialized) { - } // if (TryUpdateRound(realElapseSeconds)) // { @@ -128,123 +80,6 @@ namespace Procedure #region Other Methods - /// - /// 初始化流程级状态并订阅事件。 - /// - private void InitializeProcedureState() - { - ResetRoundState(); - GameEntry.Event.Subscribe(CombineCompletedEventArgs.EventId, OnPuzzleCompleted); - - _combineComponent = GameEntry.Combine; - if (_combineComponent == null) - { - Log.Warning("{0} START failed. CombineComponent is missing.", LogPrefix); - } - - Log.Info("{0} START timeout={1}s restartDelay={2}s.", LogPrefix, TimeoutSeconds.ToString("F0"), - RestartDelaySeconds.ToString("F0")); - } - - /// - /// 清理流程级状态并反订阅事件。 - /// - private void ShutdownProcedureState() - { - GameEntry.Event.Unsubscribe(CombineCompletedEventArgs.EventId, OnPuzzleCompleted); - _combineComponent?.StopLevel(); - ResetRoundState(); - } - - /// - /// 更新当前局状态。 - /// 返回 true 表示流程仍在关卡运行阶段,不进入重开逻辑。 - /// - private bool TryUpdateRound(float realElapseSeconds) - { - if (_isFinished) - { - return false; - } - - if (!_isStarted) - { - TryStartPuzzle(); - return true; - } - - UpdateTimeout(realElapseSeconds); - return true; - } - - /// - /// 启动拼装关卡并记录开始信息。 - /// - private void TryStartPuzzle() - { - if (_combineComponent == null) - { - Log.Warning("{0} FAIL_NO_COMPONENT reason='CombineComponentMissing'.", LogPrefix); - FinishAndScheduleRestart(false); - return; - } - - CombineFormContext context = BuildTestOpenData(); - int? serialId = _combineComponent.StartLevel(context); - - if (!serialId.HasValue) - { - Log.Warning("{0} FAIL_NO_CONTEXT reason='StartLevelFailed'.", LogPrefix); - FinishAndScheduleRestart(false); - return; - } - - _isStarted = true; - _elapsed = 0f; - _startTimestamp = Time.realtimeSinceStartup; - Log.Info("{0} START uiFormId={1} serialId={2}.", LogPrefix, ((int)UIFormId.CombineForm).ToString(), - serialId.ToString()); - } - - /// - /// 更新超时计时;超时后按失败结算。 - /// - private void UpdateTimeout(float realElapseSeconds) - { - _elapsed += realElapseSeconds; - if (_elapsed < TimeoutSeconds) - { - return; - } - - _elapsed = TimeoutSeconds; - Log.Warning("{0} FAIL_TIMEOUT elapsed={1:F2}s timeout={2:F2}s.", LogPrefix, _elapsed, TimeoutSeconds); - FinishAndScheduleRestart(false); - } - - /// - /// 结算后推进重开倒计时,到时切换到换场景流程。 - /// - private void TryRestartScene(ProcedureOwner procedureOwner, float realElapseSeconds) - { - if (!_isFinished) - { - return; - } - - _restartCountdown -= realElapseSeconds; - if (_restartCountdown > 0f) - { - return; - } - - int nextSceneId = (int)SceneId.GameplayA; - procedureOwner.SetData("NextSceneId", nextSceneId); - Log.Info("{0} RESTART result={1} nextSceneId={2}.", LogPrefix, _isPassed ? "PASS" : "FAIL", - nextSceneId.ToString()); - ChangeState(procedureOwner); - } - /// /// 构建测试用关卡上下文(槽位、部件与自动开始配置)。 /// @@ -321,50 +156,6 @@ namespace Procedure }; } - /// - /// 拼装完成事件回调:记录耗时并按成功结算。 - /// - private void OnPuzzleCompleted(object sender, GameEventArgs e) - { - if (!(e is CombineCompletedEventArgs)) - { - return; - } - - if (_isFinished) - { - return; - } - - _elapsed = Mathf.Max(0f, Time.realtimeSinceStartup - _startTimestamp); - Log.Info("{0} PASS elapsed={1:F2}s.", LogPrefix, _elapsed); - FinishAndScheduleRestart(true); - } - - /// - /// 标记当前局结束,并开始重开倒计时。 - /// - private void FinishAndScheduleRestart(bool isPassed) - { - _isPassed = isPassed; - _isFinished = true; - _restartCountdown = RestartDelaySeconds; - } - - /// - /// 重置局内运行态字段。 - /// - private void ResetRoundState() - { - _isStarted = false; - _isFinished = false; - _isPassed = false; - _elapsed = 0f; - _restartCountdown = 0f; - _startTimestamp = 0f; - _combineComponent = null; - } - #endregion } -} +} \ No newline at end of file diff --git a/Assets/GameMain/Scripts/UI/Controller/CombineFormController.cs b/Assets/GameMain/Scripts/UI/Controller/CombineFormController.cs index b582d5d..ff12bad 100644 --- a/Assets/GameMain/Scripts/UI/Controller/CombineFormController.cs +++ b/Assets/GameMain/Scripts/UI/Controller/CombineFormController.cs @@ -6,7 +6,7 @@ namespace UI { public class CombineFormController : IFormController { - private CombineComponent _controller; + private CombineComponent _combine; private CombineForm _combineForm; @@ -16,20 +16,20 @@ namespace UI public CombineFormController(CombineComponent controller) { - _controller = controller; + _combine = controller; GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess); - GameEntry.Event.Subscribe(CloseUIFormCompleteEventArgs.EventId, CloseUIFormComplete); + GameEntry.Event.Subscribe(CloseUIFormCompleteEventArgs.EventId, CloseUIFormComplete); } public int? OpenUI(CombineFormContext context) { - if (_controller == null) + if (_combine == null) { - _controller = GameEntry.Combine; + _combine = GameEntry.Combine; } - if (_controller == null) + if (_combine == null) { Log.Warning("CombineFormController open failed. Controller is null."); return null; @@ -37,10 +37,10 @@ namespace UI if (context != null) { - _controller.SetFormContext(context); + _combine.SetFormContext(context); } - _context = _controller.GetFormContext(); + _context = _combine.GetFormContext(); if (_context == null) { Log.Warning("CombineFormController open failed. Form context is null."); @@ -68,7 +68,7 @@ namespace UI ~CombineFormController() { GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess); - GameEntry.Event.Unsubscribe(CloseUIFormCompleteEventArgs.EventId, CloseUIFormComplete); + GameEntry.Event.Unsubscribe(CloseUIFormCompleteEventArgs.EventId, CloseUIFormComplete); } private void OpenUIFormSuccess(object sender, GameEventArgs e) diff --git a/Assets/GameMain/Scripts/UI/View/SettingForm.cs b/Assets/GameMain/Scripts/UI/View/SettingForm.cs index d4fbc75..7e9847c 100644 --- a/Assets/GameMain/Scripts/UI/View/SettingForm.cs +++ b/Assets/GameMain/Scripts/UI/View/SettingForm.cs @@ -44,6 +44,10 @@ namespace UI { _controller = context.Controller; + bool isMobilePlatform = Application.isMobilePlatform; + _screenSolution.gameObject.SetActive(!isMobilePlatform); + _screenWindow.gameObject.SetActive(!isMobilePlatform); + var setting = context.Setting; _bgmVolumeSlider.value = setting.BGMVolume * 5; @@ -121,7 +125,7 @@ namespace UI }; dialogParams.OnClickConfirm += SaveSettingAndReturn; dialogParams.OnClickCancel += _ => _controller.CloseUI(); - + GameEntry.UI.OpenUIForm(UIFormId.DialogForm, dialogParams); } diff --git a/Assets/Launcher.unity b/Assets/Launcher.unity index df50412..73f3e12 100644 --- a/Assets/Launcher.unity +++ b/Assets/Launcher.unity @@ -593,7 +593,7 @@ PrefabInstance: objectReference: {fileID: 934951765} - target: {fileID: 11454530, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} propertyPath: m_UIGroups.Array.size - value: 2 + value: 3 objectReference: {fileID: 0} - target: {fileID: 11454530, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} propertyPath: m_UIGroupHelperTypeName @@ -607,6 +607,10 @@ PrefabInstance: propertyPath: m_UIGroups.Array.data[1].m_Name value: Dialog objectReference: {fileID: 0} + - target: {fileID: 11454530, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} + propertyPath: m_UIGroups.Array.data[2].m_Name + value: Overlay + objectReference: {fileID: 0} - target: {fileID: 11454530, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} propertyPath: m_UIGroups.Array.data[0].m_Depth value: 0 @@ -615,6 +619,10 @@ PrefabInstance: propertyPath: m_UIGroups.Array.data[1].m_Depth value: 2 objectReference: {fileID: 0} + - target: {fileID: 11454530, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} + propertyPath: m_UIGroups.Array.data[2].m_Depth + value: 3 + objectReference: {fileID: 0} - target: {fileID: 11461470, guid: adb3eb1c35fcff14f89fba7b05c9d71c, type: 3} propertyPath: m_Enabled value: 0 @@ -858,7 +866,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: d6174838c30e460429e5628757bbf015, type: 3} m_Name: m_EditorClassIdentifier: - _playingSpeed: 10 --- !u!1 &513208572 GameObject: m_ObjectHideFlags: 0 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset index 56859a2..69f10f7 100644 --- a/ProjectSettings/GraphicsSettings.asset +++ b/ProjectSettings/GraphicsSettings.asset @@ -3,7 +3,7 @@ --- !u!30 &1 GraphicsSettings: m_ObjectHideFlags: 0 - serializedVersion: 14 + serializedVersion: 15 m_Deferred: m_Mode: 1 m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} @@ -13,9 +13,6 @@ GraphicsSettings: m_ScreenSpaceShadows: m_Mode: 1 m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} - m_LegacyDeferred: - m_Mode: 1 - m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} m_DepthNormals: m_Mode: 1 m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} @@ -37,6 +34,9 @@ GraphicsSettings: - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10752, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} m_PreloadedShaders: [] m_PreloadShadersBatchTimeLimit: -1 m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, @@ -51,6 +51,7 @@ GraphicsSettings: m_LightmapStripping: 0 m_FogStripping: 0 m_InstancingStripping: 0 + m_BrgStripping: 0 m_LightmapKeepPlain: 1 m_LightmapKeepDirCombined: 1 m_LightmapKeepDynamicPlain: 1 @@ -68,3 +69,6 @@ GraphicsSettings: m_SRPDefaultSettings: UnityEngine.Rendering.Universal.UniversalRenderPipeline: {fileID: 11400000, guid: 18dc0cd2c080841dea60987a38ce93fa, type: 2} + m_LightProbeOutsideHullStrategy: 0 + m_CameraRelativeLightCulling: 0 + m_CameraRelativeShadowCulling: 0 diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 191853f..38cf45f 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -935,7 +935,7 @@ PlayerSettings: hmiLogStartupTiming: 0 hmiCpuConfiguration: apiCompatibilityLevel: 6 - activeInputHandler: 2 + activeInputHandler: 1 windowsGamepadBackendHint: 0 cloudProjectId: framebufferDepthMemorylessMode: 0 diff --git a/数据表/Sound.txt b/数据表/Sound.txt deleted file mode 100644 index 0d22e6d..0000000 --- a/数据表/Sound.txt +++ /dev/null @@ -1,9 +0,0 @@ -# 声音配置表 -# Id AssetName Priority Loop Volume SpatialBlend MaxDistance -# int string int bool float float float -# 声音编号 策划备注 资源名称 优先级(默认0,128最高,-128最低) 是否循环 音量(0~1) 声音空间混合量(0为2D,1为3D,中间值混合效果) 声音最大距离 - 10000 玩家子弹 weapon_player 0 False 1 0 100 - 10001 敌人子弹 weapon_enemy 0 False 1 0 100 - 20000 玩家爆炸 explosion_player 0 False 1 0 100 - 20001 敌人爆炸 explosion_enemy 0 False 1 0 100 - 20002 小行星爆炸 explosion_asteroid 0 False 1 0 100 diff --git a/数据表/UIForm.txt b/数据表/UIForm.txt index c97b02d..54e9bb5 100644 --- a/数据表/UIForm.txt +++ b/数据表/UIForm.txt @@ -7,6 +7,7 @@ 101 设置 SettingForm Default False True 102 关于 AboutForm Default False True 103 组装玩法UI CombineForm Default False False - 104 Mask对话UI MaskDialogForm Default False False - 105 Bottom对话UI BottomBoxDialogForm Default False False - 106 Bubble对话UI BubbleDialogForm Default True False + 104 Mask对话UI MaskDialogForm Dialog False False + 105 Bottom对话UI BottomBoxDialogForm Dialog False False + 106 Bubble对话UI BubbleDialogForm Dialog True False + 107 游戏场景覆盖UI MainOverlayForm Overlay False False diff --git a/数据表/UIForm.xlsx b/数据表/UIForm.xlsx index 1d559d7282494421a99d8dc7ebb22978704ed5c5..0197b2972053900775f0790f3458c17d2f4e1c28 100644 GIT binary patch delta 2297 zcmZ9Oc{J3G8pmf0F?NH5moXZQZ5T>Qwy|Vr7-0}4Td!>`g*aWH-^I$y#9|-a7Z*bI*I9Kb}9HbDrgo&-s3z1wys;BLK{i#E~y*1>}O2C{ws% zEHT48>WnosK}N8kzK&%4#i0eUI^3&_+0anw;IJH{+R9*l92`E|TVD!pNw?cz>(6ec z5l$dbpgv#gDmyAUDLjnI#>|C1tP=I`;yLqA+lFU=P+asS;FXQp@z;T|8k!v2^n$%X} zN{`yI^{4Tv+ZXH~X@ao0RY7|bo} z?F+L`5iB6=A|Mcm3lwKbHz2G(Ey038pcpm~NEigXmJ@BnKxDw+G~fbzB)^J{+&OD@ z5NJja1Ud!+)KL5SBi z&qhSL1ZgI8{4u;h^{VaMTjSunC&CYS}hPPgnKjh=KiDO#m zReScB`0*9W-W;=F_$3pO_<}9g0-pY9Ovt%U{Kd>_{%TjwyZKrHj)$_dH!4g9QuY)h z=VArW!Rkv9w|Am?<`g7d$YoRC3r-0Tn(Fg%~ayE#Va{pUvU4^(1VQP!7}G3Sz=S>Vll+jtFo}ah8vAg(^9(!;t}eQ**fv%>8c@dH|> z)p5PuxgjQ~vDy|N9TQU*p|@z=6o)T~M%=B{qRzdS%e-o>zW6}l(~iefEnt#ms-!CQ zCt}2z{Tj=dvg0#oO7jPWEqR?1O2fA8c%e<{aU_00b&>IS`5I}TxzivQ#^^3z2`bMzR3bpC@?lbLARb$5Fkh4+^h&}L?2TFE>kqH{Nbbk4Ke1IBsSHYN>UQ;x)%i5787+)T#0&*BGh@3|UqQI4&12bf#XsXWvp{7PVCUf& z$yPg?iox-`aFdDLO5Zmo^2kDaMg%9rRgrV5XI?9Xj$7sK46rT zGBX(EU7my8Z&=EjAMFGQ^_SA6f@$v(bBW|sbwG|5nf~zMR7_h#Ha_oeNH}wXckkV@ zP91A8YCylna-sP%~a=Ai}Z^8=i)#zOd z@gPKN50W4gQQGE@&r01*P)1g#%DB^$w|;E+pAcWCQA_b`+4ksYOZ}J^YmBgQMW+T* zUYJ(5`iKMDHz-`XqUWjObml7ozXbJ@rXAsP$>{X&hbOrFrelL7okv+~+KKeSqwA?3 zT6?}|E%8Nd7;XAEKT1Ef=kiTW6~FI2q~CZ)XdVXM2FOSQunSO!)CAuKJ|Kbr{0c|$&?@W0^< z4)^m60-}&IfSLk7*c{MP&|(XK0#~4-K$3zI_&v~~a2A{cd{sb5{?k!^5B%>DJ%AcY K`N$pQ@57Ep_ zlR_pjk!x3?vPDEDvK!0Gx%a&Hyw5q$dCqyB@Av!HbIzyOVa&c90=UD1nDa#FKA;JH zBw61sXvu(u7a-3hVgp&PYDFr%hVE3GiI%l6JIWWtj}fF@V_If7yBu~CwA79#_wqYC zeRzpIs;I$*4se+z#{^6Cugh3>T|q~ZFKYCN%Vd@JLzMf(0rB9#Am%2Lg0dO*X-3iJ z8{74+dI~1gs~igx&a5GSrWd+j0N=EVdH^I|DKGAaw(R4?;o8{*g4m+ZE zE)RQy?vGnc8H^*dyYG;WhZgmP*nRYuSW87)>mFh!X(7D&j}i=LJ#THHM!QR=zZ6}1 z`pJzKtDUJNDqdHH{v&QNPww@%^}Jzf`9xQDb48|VTOyis9o*iE=vWLnqdN9-*+SGC z^~?LW&Bn_nFB@EmBDMt6WZtB+l?wj&w^E8i^J9;8j6FQ;>lb&C{rCIsMc`B7Z@}g* z%kT283fkKqfTLhA*g+VbG=XjHD4VVlJ8%L3${{j5itmhcrM)^F2AdaxKEdU|%!?_H zj8S)*oMu66lt(c1fQTnJno;^rKdTP7_Ng154HrDmN4meUb|VlG_2p;+im|=E-mrS( zAQg-b37C%E%x|7&2{tmr?cK&I15%{dIM09dSIr5igmg5p(8G1|w9peF;I@y@vL zMJpLb&mrkGE1R_m&dEzSI}8|6cM`oU6FNExk6t|m&RkE=475MXaS%4&u%p)Kq%8D} ziXM>|=>tutozuNTD7-?4r%~kYRW``=>m@k=FnB0F7JNvZ2tGC1;4klIVFN)^|j zY%*G=W5(3l3GCp(K*X!novZGS2)TmvPA_q%* zUg{;;*%%8}2x?0fu$X|*XdCDu0zViND!akdTNY25ShAV>X4-S)<1Y{HCou}(J%Cb( zEtzCX@+l43*HP(s{tz*nT(c`TDJ}|iq~j&#gpLWSemU5#Eliod%l_*^q%7Z{{|qF7 zNfatse#X7B(PePfAva{uLQXbIF77n( zUZwfLg5s(00WTSnrS<_X%AXXCsov2YvA(pv~m7(LHTMT0i_9OM!A@W0Dpm$a*aZkp#gt^ zi+U;u(b)ztS@Mx`erEg)H4O`*J9)5uNb`jdLLE77#P4 z!yTn&ILB8`n;LymRYUqa>}k+6HDyX6DDLftRJv0jDpw(%Q%#;hogDIQJzLfz<^Pzd z&G3CU5K9yFG4LGp-xonUDOntX+ijAamHA#)O(j8_p&?!C`jlJbxPb~JQcr?}^-(!m z#iU`)umCfW|1|ziYQ&%!)Le0^$+qx!4EJd?u2-sgyrnX~#6{zMt=2=ZUiInlNtFtH zSE)i{yhO3y)fy8Ka_LIvlu3L-;(Hyv$aQM zWgVva)`Y7l5rbF&ybQK)D)as9 za8|bP?L@513#H0c(Ri^uyd%oCNa<6xSG zgtbi%BJ^-slFbjKnVt?kOOW>^8FJ09R16}1&84Mj=FPDlJ|;ChXS%bq(>t<9uO)BE zy6N9D;qtf4&x&@Oi-|yv%N-1-?N&91{cCK-Ah-}jOe`cO1UZr4r7Nu-XbV%Lc+gTX)SX!_`X0g+ukyqt`E?$xG45@ay#`JDWc&Bk5}~P+~g)7 z`dC~_f8z51XXBh@kEPDvE-mN0ZE9_I+|18hb$eiEw6Jvcl?CC@^K%PKD5aPR4xGmi zYbGg^{830`p^`)=&NU_Vs2^?#`12vndZCkMVjf5gP;%Hs)R-nM`K#Q zcMW;Eo!VF+m(ttC-p@C+Tqi$F z?J_qJ{|}hbsu__UBv1^!P{9HyXj8=yI0oscLjMq*rD`g(&mi31yWHY}!9@4Sv|j*B zVSgNeZse^0na zv;FOU{hb;F38-5Fc@Rn66p)4D)r|owh^dYRk|99D97u;S8j3Riau5cS{M-DGn+bD*KoJ0`Y(3>i_@%