From 325aa911442b8310b53be5312abf8eee0dc31b02 Mon Sep 17 00:00:00 2001 From: Venuska1117 Date: Fri, 10 Jul 2026 10:20:41 +0200 Subject: [PATCH] upgrade --- .../abilities/predalien/predalien_powers.dm | 288 ------------------ .../carbon/xenomorph/castes/Predalien.dm | 280 ++++++++++++++++- colonialmarines.dme | 1 - sound/effects/pred_force_decloak.ogg | Bin 0 -> 30907 bytes 4 files changed, 279 insertions(+), 290 deletions(-) delete mode 100644 code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm create mode 100644 sound/effects/pred_force_decloak.ogg diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm deleted file mode 100644 index 6cba9882d316e..0000000000000 --- a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm +++ /dev/null @@ -1,288 +0,0 @@ -/datum/action/xeno_action/onclick/predalien_roar/use_ability(atom/target) - var/mob/living/carbon/xenomorph/xeno = owner - - if(!action_cooldown_check()) - return - - if(!xeno.check_state()) - return - - if(!check_and_use_plasma_owner()) - return - - playsound(xeno.loc, pick(predalien_roar), 75, 0, status = 0) - xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] emits a guttural roar!")) - xeno.create_shriekwave(7) //Adds the visual effect. Wom wom wom, 7 shriekwaves - FOR_DVIEW(var/mob/living/carbon/carbon, 7, xeno, HIDE_INVISIBLE_OBSERVER) - if(ishuman(carbon)) - var/mob/living/carbon/human/human = carbon - human.disable_special_items() - - var/obj/item/clothing/gloves/yautja/hunter/YG = locate(/obj/item/clothing/gloves/yautja/hunter) in human - if(isyautja(human) && YG) - if(HAS_TRAIT(human, TRAIT_CLOAKED)) - YG.decloak(human, TRUE, DECLOAK_PREDALIEN) - - YG.cloak_timer = xeno_cooldown * 0.1 - else if(isxeno(carbon) && xeno.can_not_harm(carbon)) - var/datum/behavior_delegate/predalien_base/behavior = xeno.behavior_delegate - if(!istype(behavior)) - continue - new /datum/effects/xeno_buff(carbon, xeno, ttl = (0.25 SECONDS * behavior.kills + 3 SECONDS), bonus_damage = bonus_damage_scale * behavior.kills, bonus_speed = (bonus_speed_scale * behavior.kills)) - FOR_DVIEW_END - - apply_cooldown() - return ..() - -/datum/action/xeno_action/activable/feralfrenzy/use_ability(atom/target) - var/mob/living/carbon/xenomorph/xeno = owner - if(!action_cooldown_check() || xeno.action_busy) - return - if(!xeno.check_state()) - return - - var/datum/behavior_delegate/predalien_base/predalienbehavior = xeno.behavior_delegate - if(!istype(predalienbehavior)) - return - if(targeting == AOETARGETGUT) - xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] begins digging in for a massive strike!"), SPAN_XENOHIGHDANGER("We begin digging in for a massive strike!")) - ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Eviscerate")) - xeno.anchored = TRUE - if (do_after(xeno, (activation_delay_aoe), INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) - xeno.emote("roar") - xeno.spin_circle() - - for (var/mob/living/carbon/carbon in orange(xeno, range)) - if(!isliving(carbon) || xeno.can_not_harm(carbon)) - continue - - if (carbon.stat == DEAD) - continue - - if(!check_clear_path_to_target(xeno, carbon)) - continue - - xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] rips open the guts of [carbon]!"), SPAN_XENOHIGHDANGER("We rip open the guts of [carbon]!")) - carbon.spawn_gibs() - xeno.animation_attack_on(carbon) - xeno.spin_circle() - xeno.flick_attack_overlay(carbon, "tail") - playsound(get_turf(carbon), 'sound/effects/gibbed.ogg', 30, 1) - carbon.apply_effect(get_xeno_stun_duration(carbon, 0.5), WEAKEN) - playsound(get_turf(carbon), "alien_claw_flesh", 30, 1) - carbon.apply_armoured_damage(get_xeno_damage_slash(carbon, base_damage_aoe + damage_scale_aoe * predalienbehavior.kills), ARMOR_MELEE, BRUTE, "chest", 20) - playsound(owner, 'sound/voice/predalien_death.ogg', 75, 0, status = 0) - REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Eviscerate")) - xeno.anchored = FALSE - apply_cooldown() - return ..() - - //single target checks - if(xeno.can_not_harm(target)) - to_chat(xeno, SPAN_XENOWARNING("We must target a hostile!")) - return - - if(!isliving(target)) - return - - if(get_dist_sqrd(target, xeno) > 2) - to_chat(xeno, SPAN_XENOWARNING("[target] is too far away!")) - return - - var/mob/living/carbon/carbon = target - - if(carbon.stat == DEAD) - to_chat(xeno, SPAN_XENOWARNING("[carbon] is dead, why would we want to touch them?")) - return - if(targeting == SINGLETARGETGUT) // single target - ADD_TRAIT(carbon, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate")) - apply_cooldown() - - ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate")) - xeno.anchored = TRUE - - if(do_after(xeno, activation_delay, INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) - xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] rips open the guts of [carbon]!"), SPAN_XENOHIGHDANGER("We rapidly slice into [carbon]!")) - carbon.spawn_gibs() - playsound(get_turf(carbon), 'sound/effects/gibbed.ogg', 50, 1) - carbon.apply_effect(get_xeno_stun_duration(carbon, 0.5), WEAKEN) - carbon.apply_armoured_damage(get_xeno_damage_slash(carbon, base_damage + damage_scale * predalienbehavior.kills), ARMOR_MELEE, BRUTE, "chest", 20) - - xeno.animation_attack_on(carbon) - xeno.spin_circle() - xeno.flick_attack_overlay(carbon, "tail") - - playsound(owner, 'sound/voice/predalien_growl.ogg', 50, 0, status = 0) - - REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate")) - xeno.anchored = FALSE - unroot_human(carbon, TRAIT_SOURCE_ABILITY("Devastate")) - - return ..() - - -/datum/action/xeno_action/onclick/feralrush/use_ability(atom/A) - var/mob/living/carbon/xenomorph/predatoralien = owner - - if(!action_cooldown_check()) - return - - if(!istype(predatoralien) || !predatoralien.check_state()) - return - - if(armor_buff && speed_buff) - to_chat(predatoralien, SPAN_XENOHIGHDANGER("We cannot stack this!")) - return - - if(!check_and_use_plasma_owner()) - return - - - addtimer(CALLBACK(src, PROC_REF(remove_rush_effects)), speed_duration) - addtimer(CALLBACK(src, PROC_REF(remove_armor_effects)), armor_duration) // calculate armor and speed differently, so it's a bit more armored while trying to get out - predatoralien.add_filter("predalien_toughen", 1, list("type" = "outline", "color" = "#421313", "size" = 1)) - to_chat(predatoralien, SPAN_XENOWARNING("We feel our muscles tense as our speed and armor increase!")) - speed_buff = TRUE - armor_buff = TRUE - predatoralien.speed_modifier -= speed_buff_amount - predatoralien.armor_modifier += armor_buff_amount - predatoralien.recalculate_speed() - predatoralien.recalculate_armor() - playsound(predatoralien, 'sound/voice/predalien_growl.ogg', 75, 0, status = 0) - apply_cooldown() - return ..() - - -/datum/action/xeno_action/onclick/feralrush/proc/remove_rush_effects() - SIGNAL_HANDLER - var/mob/living/carbon/xenomorph/predatoralien = owner - if(speed_buff == TRUE) - to_chat(predatoralien, SPAN_XENOWARNING("Our muscles relax as we feel our speed wane.")) - predatoralien.remove_filter("predalien_toughen") - predatoralien.speed_modifier += speed_buff_amount - predatoralien.recalculate_speed() - speed_buff = FALSE - - -/datum/action/xeno_action/onclick/feralrush/proc/remove_armor_effects() - SIGNAL_HANDLER - var/mob/living/carbon/xenomorph/predatoralien = owner - if(armor_buff) - to_chat(predatoralien, SPAN_XENOWARNING("We are no longer armored.")) - predatoralien.armor_modifier -= armor_buff_amount - predatoralien.recalculate_armor() - armor_buff = FALSE - - -/datum/action/xeno_action/onclick/toggle_gut_targeting/use_ability(atom/A) - - var/mob/living/carbon/xenomorph/xeno = owner - var/action_icon_result - - if(!xeno.check_state()) - return - - var/datum/action/xeno_action/activable/feralfrenzy/guttype = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) - if(!guttype) - return - - if(guttype.targeting == SINGLETARGETGUT) - action_icon_result = "rav_scissor_cut" - guttype.targeting = AOETARGETGUT - to_chat(xeno, SPAN_XENOWARNING("We will now attack everyone around us during a Feral Frenzy.")) - else - action_icon_result = "rav_shard_shed" - guttype.targeting = SINGLETARGETGUT - to_chat(xeno, SPAN_XENOWARNING("We will now focus our Feral Frenzy on one person!")) - - button.overlays.Cut() - button.overlays += image('icons/mob/hud/actions_xeno.dmi', button, action_icon_result) - return ..() - -/datum/action/xeno_action/activable/feral_smash/use_ability(atom/affected_atom) - var/mob/living/carbon/xenomorph/predalien_smash = owner - var/datum/behavior_delegate/predalien_base/predalienbehavior = predalien_smash.behavior_delegate - - if(!action_cooldown_check()) - if(twitch_message_cooldown < world.time ) - predalien_smash.visible_message(SPAN_XENOWARNING("[predalien_smash]'s muscles twitch."), SPAN_XENOWARNING("Our claws twitch as we try to grab onto the target but lack the strength. Wait a moment to try again.")) - twitch_message_cooldown = world.time + 5 SECONDS - return //this gives a little feedback on why your lunge didn't hit other than the lunge button going grey. Plus, it might spook marines that almost got lunged if they know why the message appeared, and extra spookiness is always good. - - if(!affected_atom) - return - - if(!isturf(predalien_smash.loc)) - to_chat(predalien_smash, SPAN_XENOWARNING("We can't lunge from here!")) - return - - if(!predalien_smash.check_state() || predalien_smash.agility) - return - - if(predalien_smash.can_not_harm(affected_atom) || !ismob(affected_atom)) - return - - - var/mob/living/carbon/carbon = affected_atom - if(carbon.stat == DEAD) - return - - if(!isliving(affected_atom)) - return - - if(!check_and_use_plasma_owner()) - return - - apply_cooldown() - - predalien_smash.throw_atom(get_step_towards(affected_atom, predalien_smash), grab_range, SPEED_FAST, predalien_smash, tracking=TRUE) - - if(predalien_smash.Adjacent(carbon) && predalien_smash.start_pulling(carbon, TRUE)) - playsound(carbon.pulledby, 'sound/voice/predalien_growl.ogg', 75, 0, status = 0) // bang and roar for dramatic effect - playsound(carbon, 'sound/effects/bang.ogg', 25, 0) - animate(carbon, pixel_y = carbon.pixel_y + 32, time = 4, easing = SINE_EASING) - sleep(4) - playsound(carbon, 'sound/effects/bang.ogg', 25, 0) - playsound(carbon,"slam", 50, 1) - animate(carbon, pixel_y = 0, time = 4, easing = BOUNCE_EASING) //animates the smash - carbon.apply_armoured_damage(get_xeno_damage_slash(carbon, smash_damage + smash_scale * predalienbehavior.kills), ARMOR_MELEE, BRUTE, "chest", 20) - else - predalien_smash.visible_message(SPAN_XENOWARNING("[predalien_smash]'s claws twitch."), SPAN_XENOWARNING("We couldn't grab our target. Wait a moment to try again.")) - - return ..() - -/mob/living/carbon/xenomorph/predalien/stop_pulling() - if(isliving(pulling) && smashing) - smashing = FALSE // To avoid extreme cases of stopping a lunge then quickly pulling and stopping to pull someone else - var/mob/living/smashed = pulling - smashed.set_effect(0, STUN) - smashed.set_effect(0, WEAKEN) - return ..() - -/mob/living/carbon/xenomorph/predalien/start_pulling(atom/movable/movable_atom, feral_smash) - if(!check_state()) - return FALSE - - if(!isliving(movable_atom)) - return FALSE - var/mob/living/living_mob = movable_atom - var/should_neckgrab = !(src.can_not_harm(living_mob)) && feral_smash - - - . = ..(living_mob, feral_smash, should_neckgrab) - - if(.) //successful pull - if(isxeno(living_mob)) - var/mob/living/carbon/xenomorph/xeno = living_mob - if(xeno.tier >= 2) // Tier 2 castes or higher immune to warrior grab stuns - return - - if(should_neckgrab && living_mob.mob_size < MOB_SIZE_BIG) - visible_message(SPAN_XENOWARNING("[src] grabs [living_mob] by the back of their leg and slams them onto the ground!"), - SPAN_XENOWARNING("We grab [living_mob] by the back of their leg and slam them onto the ground!")) // more flair - smashing = TRUE - living_mob.drop_held_items() - var/duration = get_xeno_stun_duration(living_mob, 1) - living_mob.KnockDown(duration) - living_mob.Stun(duration) - addtimer(VARSET_CALLBACK(src, smashing, FALSE), duration) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm index 8a3ad059710fa..15352fa40452a 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm @@ -154,7 +154,7 @@ You must still listen to the queen. . = list() . += "Kills: [kills]/[max_kills]" -/datum/behavior_delegate/predalien_base/on_kill_mob(mob/M) +/datum/behavior_delegate/predalien_base/on_kill_mob(mob/target_mob) . = ..() kills = min(kills + 1, max_kills) @@ -166,3 +166,281 @@ You must still listen to the queen. original_damage *= 1.5 return original_damage + kills * 2.5 + +/datum/action/xeno_action/onclick/predalien_roar/use_ability(atom/target_atom) + var/mob/living/carbon/xenomorph/xeno = owner + + XENO_ACTION_CHECK_USE_PLASMA(xeno) + + playsound(xeno.loc, pick(predalien_roar), 75, 0, status = 0) + xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] emits a guttural roar!")) + xeno.create_shriekwave(7) //Adds the visual effect. Wom wom wom, 7 shriekwaves + FOR_DVIEW(var/mob/living/carbon/target_carbon, 7, xeno, HIDE_INVISIBLE_OBSERVER) + if(ishuman(target_carbon)) + var/mob/living/carbon/human/target_human = target_carbon + target_human.disable_special_items() + + var/obj/item/clothing/gloves/yautja/hunter/yautja_glove = locate(/obj/item/clothing/gloves/yautja/hunter) in target_human + if(isyautja(target_human) && yautja_glove) + if(HAS_TRAIT(target_human, TRAIT_CLOAKED)) + yautja_glove.decloak(target_human, TRUE, DECLOAK_PREDALIEN) + target_human.add_filter("uncloack", 1, list("type" = "outline", "color" = "#32fff58c", "size" = 1.5)) + addtimer(CALLBACK(src, PROC_REF(disable_filter), target_human), 3 SECONDS) + playsound(target_human.loc, 'sound/effects/pred_force_decloak.ogg', 100, 1, 10) + + yautja_glove.cloak_timer = xeno_cooldown * 0.1 + else if(isxeno(target_carbon) && xeno.can_not_harm(target_carbon)) + var/datum/behavior_delegate/predalien_base/behavior = xeno.behavior_delegate + if(!istype(behavior)) + continue + new /datum/effects/xeno_buff(target_carbon, xeno, ttl = (0.25 SECONDS * behavior.kills + 3 SECONDS), bonus_damage = bonus_damage_scale * behavior.kills, bonus_speed = (bonus_speed_scale * behavior.kills)) + FOR_DVIEW_END + + apply_cooldown() + return ..() + +/datum/action/xeno_action/onclick/predalien_roar/proc/disable_filter(mob/living/carbon/human/target_human) + target_human.remove_filter("uncloack") + +/datum/action/xeno_action/activable/feralfrenzy/use_ability(atom/target_atom) + var/mob/living/carbon/xenomorph/xeno = owner + if(xeno.action_busy) + return + + XENO_ACTION_CHECK(xeno) + + var/datum/behavior_delegate/predalien_base/predalienbehavior = xeno.behavior_delegate + if(!istype(predalienbehavior)) + return + if(targeting == AOETARGETGUT) + xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] begins digging in for a massive strike!"), SPAN_XENOHIGHDANGER("We begin digging in for a massive strike!")) + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Eviscerate")) + xeno.anchored = TRUE + if(do_after(xeno, (activation_delay_aoe), INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + xeno.emote("roar") + xeno.spin_circle() + + for(var/mob/living/carbon/target_carbon in orange(xeno, range)) + if(!isliving(target_carbon) || xeno.can_not_harm(target_carbon)) + continue + + if(target_carbon.stat == DEAD) + continue + + if(!check_clear_path_to_target(xeno, target_carbon)) + continue + + xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] rips open the guts of [target_carbon]!"), SPAN_XENOHIGHDANGER("We rip open the guts of [target_carbon]!")) + target_carbon.spawn_gibs() + xeno.animation_attack_on(target_carbon) + xeno.spin_circle() + xeno.flick_attack_overlay(target_carbon, "tail") + playsound(get_turf(target_carbon), 'sound/effects/gibbed.ogg', 30, 1) + target_carbon.apply_effect(get_xeno_stun_duration(target_carbon, 0.5), WEAKEN) + playsound(get_turf(target_carbon), "alien_claw_flesh", 30, 1) + target_carbon.apply_armoured_damage(get_xeno_damage_slash(target_carbon, base_damage_aoe + damage_scale_aoe * predalienbehavior.kills), ARMOR_MELEE, BRUTE, "chest", 20) + playsound(owner, 'sound/voice/predalien_death.ogg', 75, 0, status = 0) + REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Eviscerate")) + xeno.anchored = FALSE + apply_cooldown() + return ..() + + //single target checks + if(xeno.can_not_harm(target_atom)) + to_chat(xeno, SPAN_XENOWARNING("We must target a hostile!")) + return + + if(!isliving(target_atom)) + return + + if(get_dist_sqrd(target_atom, xeno) > 2) + to_chat(xeno, SPAN_XENOWARNING("[target_atom] is too far away!")) + return + + var/mob/living/carbon/target_carbon = target_atom + + if(target_carbon.stat == DEAD) + to_chat(xeno, SPAN_XENOWARNING("[target_carbon] is dead, why would we want to touch them?")) + return + if(targeting == SINGLETARGETGUT) // single target + ADD_TRAIT(target_carbon, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate")) + apply_cooldown() + + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate")) + xeno.anchored = TRUE + + if(do_after(xeno, activation_delay, INTERRUPT_ALL | BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + xeno.visible_message(SPAN_XENOHIGHDANGER("[xeno] rips open the guts of [target_carbon]!"), SPAN_XENOHIGHDANGER("We rapidly slice into [target_carbon]!")) + target_carbon.spawn_gibs() + playsound(get_turf(target_carbon), 'sound/effects/gibbed.ogg', 50, 1) + target_carbon.apply_effect(get_xeno_stun_duration(target_carbon, 0.5), WEAKEN) + target_carbon.apply_armoured_damage(get_xeno_damage_slash(target_carbon, base_damage + damage_scale * predalienbehavior.kills), ARMOR_MELEE, BRUTE, "chest", 20) + + xeno.animation_attack_on(target_carbon) + xeno.spin_circle() + xeno.flick_attack_overlay(target_carbon, "tail") + + playsound(owner, 'sound/voice/predalien_growl.ogg', 50, 0, status = 0) + + REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_ABILITY("Devastate")) + xeno.anchored = FALSE + unroot_human(target_carbon, TRAIT_SOURCE_ABILITY("Devastate")) + + return ..() + + +/datum/action/xeno_action/onclick/feralrush/use_ability(atom/target_atom) + var/mob/living/carbon/xenomorph/xeno = owner + if(!istype(xeno)) + return + + if(armor_buff && speed_buff) + to_chat(xeno, SPAN_XENOHIGHDANGER("We cannot stack this!")) + return + + XENO_ACTION_CHECK_USE_PLASMA(xeno) + + addtimer(CALLBACK(src, PROC_REF(remove_rush_effects)), speed_duration) + addtimer(CALLBACK(src, PROC_REF(remove_armor_effects)), armor_duration) // calculate armor and speed differently, so it's a bit more armored while trying to get out + xeno.add_filter("predalien_toughen", 1, list("type" = "outline", "color" = "#421313", "size" = 1)) + to_chat(xeno, SPAN_XENOWARNING("We feel our muscles tense as our speed and armor increase!")) + speed_buff = TRUE + armor_buff = TRUE + xeno.speed_modifier -= speed_buff_amount + xeno.armor_modifier += armor_buff_amount + xeno.recalculate_speed() + xeno.recalculate_armor() + playsound(xeno, 'sound/voice/predalien_growl.ogg', 75, 0, status = 0) + apply_cooldown() + return ..() + + +/datum/action/xeno_action/onclick/feralrush/proc/remove_rush_effects() + SIGNAL_HANDLER + var/mob/living/carbon/xenomorph/xeno = owner + if(speed_buff == TRUE) + to_chat(xeno, SPAN_XENOWARNING("Our muscles relax as we feel our speed wane.")) + xeno.remove_filter("predalien_toughen") + xeno.speed_modifier += speed_buff_amount + xeno.recalculate_speed() + speed_buff = FALSE + + +/datum/action/xeno_action/onclick/feralrush/proc/remove_armor_effects() + SIGNAL_HANDLER + var/mob/living/carbon/xenomorph/xeno = owner + if(armor_buff) + to_chat(xeno, SPAN_XENOWARNING("We are no longer armored.")) + xeno.armor_modifier -= armor_buff_amount + xeno.recalculate_armor() + armor_buff = FALSE + + +/datum/action/xeno_action/onclick/toggle_gut_targeting/use_ability(atom/target_atom) + var/mob/living/carbon/xenomorph/xeno = owner + var/action_icon_result + + XENO_ACTION_CHECK(xeno) + + var/datum/action/xeno_action/activable/feralfrenzy/guttype = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + if(!guttype) + return + + if(guttype.targeting == SINGLETARGETGUT) + action_icon_result = "rav_scissor_cut" + guttype.targeting = AOETARGETGUT + to_chat(xeno, SPAN_XENOWARNING("We will now attack everyone around us during a Feral Frenzy.")) + else + action_icon_result = "rav_shard_shed" + guttype.targeting = SINGLETARGETGUT + to_chat(xeno, SPAN_XENOWARNING("We will now focus our Feral Frenzy on one person!")) + + button.overlays.Cut() + button.overlays += image('icons/mob/hud/actions_xeno.dmi', button, action_icon_result) + return ..() + +/datum/action/xeno_action/activable/feral_smash/use_ability(atom/affected_atom) + var/mob/living/carbon/xenomorph/xeno = owner + + if(!action_cooldown_check()) + if(twitch_message_cooldown < world.time) + xeno.visible_message(SPAN_XENOWARNING("[xeno]'s muscles twitch."), SPAN_XENOWARNING("Our claws twitch as we try to grab onto the target but lack the strength. Wait a moment to try again.")) + twitch_message_cooldown = world.time + 5 SECONDS + return //this gives a little feedback on why your lunge didn't hit other than the lunge button going grey. Plus, it might spook marines that almost got lunged if they know why the message appeared, and extra spookiness is always good. + + if(!affected_atom) + return + + if(!isturf(xeno.loc)) + to_chat(xeno, SPAN_XENOWARNING("We can't lunge from here!")) + return + + if(xeno.can_not_harm(affected_atom) || !ismob(affected_atom)) + return + + var/mob/living/carbon/target_carbon = affected_atom + if(target_carbon.stat == DEAD) + return + + if(!isliving(affected_atom)) + return + + XENO_ACTION_CHECK_USE_PLASMA(xeno) + + apply_cooldown() + + xeno.throw_atom(get_step_towards(affected_atom, xeno), grab_range, SPEED_FAST, xeno, tracking=TRUE) + + if(xeno.Adjacent(target_carbon) && xeno.start_pulling(target_carbon, TRUE)) + playsound(target_carbon.pulledby, 'sound/voice/predalien_growl.ogg', 75, 0, status = 0) // bang and roar for dramatic effect + playsound(target_carbon, 'sound/effects/bang.ogg', 25, 0) + animate(target_carbon, pixel_y = target_carbon.pixel_y + 32, time = 4, easing = SINE_EASING) + addtimer(CALLBACK(src, PROC_REF(second_smash_part), target_carbon, xeno), 4 DECISECONDS) + else + xeno.visible_message(SPAN_XENOWARNING("[xeno]'s claws twitch."), SPAN_XENOWARNING("We couldn't grab our target. Wait a moment to try again.")) + + return ..() + +/datum/action/xeno_action/activable/feral_smash/proc/second_smash_part(mob/living/carbon/target_carbon, mob/living/carbon/xenomorph/xeno) + var/datum/behavior_delegate/predalien_base/predalienbehavior = xeno.behavior_delegate + + playsound(target_carbon, 'sound/effects/bang.ogg', 25, 0) + playsound(target_carbon,"slam", 50, 1) + animate(target_carbon, pixel_y = 0, time = 4, easing = BOUNCE_EASING) //animates the smash + target_carbon.apply_armoured_damage(get_xeno_damage_slash(target_carbon, smash_damage + smash_scale * predalienbehavior.kills), ARMOR_MELEE, BRUTE, "chest", 20) + +/mob/living/carbon/xenomorph/predalien/stop_pulling() + if(isliving(pulling) && smashing) + smashing = FALSE // To avoid extreme cases of stopping a lunge then quickly pulling and stopping to pull someone else + var/mob/living/smashed = pulling + smashed.set_effect(0, STUN) + smashed.set_effect(0, WEAKEN) + return ..() + +/mob/living/carbon/xenomorph/predalien/start_pulling(atom/movable/movable_atom, feral_smash) + if(!check_state()) + return FALSE + + if(!isliving(movable_atom)) + return FALSE + var/mob/living/living_mob = movable_atom + var/should_neckgrab = !(src.can_not_harm(living_mob)) && feral_smash + + + . = ..(living_mob, feral_smash, should_neckgrab) + + if(.) //successful pull + if(isxeno(living_mob)) + var/mob/living/carbon/xenomorph/xeno = living_mob + if(xeno.tier >= 2) // Tier 2 castes or higher immune to warrior grab stuns + return + + if(should_neckgrab && living_mob.mob_size < MOB_SIZE_BIG) + visible_message(SPAN_XENOWARNING("[src] grabs [living_mob] by the back of their leg and slams them onto the ground!"), + SPAN_XENOWARNING("We grab [living_mob] by the back of their leg and slam them onto the ground!")) // more flair + smashing = TRUE + living_mob.drop_held_items() + var/duration = get_xeno_stun_duration(living_mob, 1) + living_mob.KnockDown(duration) + living_mob.Stun(duration) + addtimer(VARSET_CALLBACK(src, smashing, FALSE), duration) diff --git a/colonialmarines.dme b/colonialmarines.dme index 4ba1e4ccaf470..6a9b3b90f3fd6 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -2246,7 +2246,6 @@ #include "code\modules\mob\living\carbon\xenomorph\abilities\praetorian\praetorian_macros.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\predalien\predalien_abilities.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\predalien\predalien_macros.dm" -#include "code\modules\mob\living\carbon\xenomorph\abilities\predalien\predalien_powers.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\queen\queen_abilities.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\queen\queen_macros.dm" #include "code\modules\mob\living\carbon\xenomorph\abilities\queen\queen_powers.dm" diff --git a/sound/effects/pred_force_decloak.ogg b/sound/effects/pred_force_decloak.ogg new file mode 100644 index 0000000000000000000000000000000000000000..672a5314a3b2f7d36f04227dddf01eb1b1b76840 GIT binary patch literal 30907 zcmeFZcT`hP*C>1vAcSfH1VS~0A|+r#6HqjiAYB4U3?K@jNLOig451i85do2^5PB#A z0%Aew0s_*jpkhP8j=gXX`g@-D`QGoYd%v~r`u@AK<_!DH?3sOLmzh2LoUrHML013@ z{FCx6{sOXBMdu(&kmy6+`Lny7}xoyy}$wBm% zwD2O6Kquo0j39^n$V8~~le$k>c~g0C*s!J=T+B@X~gav$Kc(!JFPB=K!-)Uh0COA!C_jxJX2B~`u3PYo+dp_XEl7^%D zBv*JT;BLeY zFz=4E>d$f*T65U+FClD*9RP>~g`Oh{{UA47bjHIC_ePjaM>tM{tk~el|2oC~(HC$c z%7y;fK}@)Qy7wQpFu`Hb#c)f}zmz}(cJWh8-bmiZArtYuXGK*~`Qsf)l>9B%t8()H zNHAnr_6aCU&4JvWqTG?Zh+$jNyt2R0afy7v+Nv?IPWDBCc(1HCh!;4PCs;L02m88> z1YrCpAXBXKmWs$5uGsgfxJmQZQ|Eu_; z%73-EG=rlxpmB9j?;dWWsOcIuU8(OvSc(!rEyfvwTAbSa{8B`niA``>^OU=GS(b~P zX4zkh0)>k4O*eIl|tPc z9qM*5YW`Y+=SC+FVQxC`_{&&Utx8(q!(Zv6;$t*?+;ch{klZDV<0sqT#j!4}- zuh4&9)xJ^HaSS)~!C=ovgHcHm*}%~i;8{oTg%%q3V{QemwhNQeIW=rI%G);s0hi z0i22)P6eCuf}N(3lpUCq$GgrA8K_&i@xRUgww&GJs$d2!hZL^*AC}WjP_P88sS)S+ z@$VeXMnQ%~l4Sl<007XQE^7a09U;5uOu86Oy68|TX8&u80b3^x9LEhn#$NcdL_aMp zpEw~d!ALhrG7o^;b}RJkGksZ5vM=Rqx{9^!Yh~9#1b=hRh;4$@#FBfEVgw~Qwbs|h zT&JbiMfq8!Ah_(ofnr%e{4PYnkx#*%5460EWIGNxNFd z8hG>m=MTpO0478bU;>f@#D70iiH!sR7-#spf&PU}h93lA`ng>a1b_^`<4XVYVgA3@ z{x^aUrUn3<<fV?E`KfVsSs=IX2+n@o>bxK51SMe&KoEK9#qn~X`yau1YjC)MP;h$z*)FibcB240 zoVas9pB;cv1==4QXFog6)!=~s6K~)M?%qc$vXrAM)$`&LdiIMXu0~!t?}jc&=>DHA z3UuxQ^8Q_I;3x&I!r*G`DUrqA_^U;R%T~{J;m$+w;j{44S-9wXh>RFNly(E<=Ov zO_h|-hL4k#K>+<^C%gU}ux?A4FNjx=>0%1jiGvPDB#2U)t#r0*@P9hWdwzrYD>vFfzDN1Vwr*_SI1vEYa~J@$>b;}l zGr0}z;6?}CIMT!u;F_S%1ye3XSlDPLr2jwFAHoFtFcJTpP>fQ%|ACGO|L3XYzs@iJ ze?l|v!L`ja06m<*M|6u%)vr-4M5V!G#n+nrNu z!6v}VN+;Yy2-5dW1dB_v+&P*pOQ3+jI&doP`$Uw>vfPt(TG06+%AnMO!8#v(yJoNs zoJugx?mAf4(1Q+6C28b)Y_tZ~8frd^uy2@j_o-=CFG$lB*7g91QA$if?LFuREwXLVhW!I+Ixu!vX-&%orf5q0P6*Ql-61 zgk+SMe*|+KJVS!2*Sn!%8+zqZijDx)3=_X`5-WxOX)p)fOHgLAKL2Vcj?Zuz0DEjS zfaKK5CjR!&*zknys{Y+jmX+o5r!V}Eiwqt`H#}7dP>N2JufPqu@zKqrrY~r%m-}k3R!SXSXDxbR#{GFw#B_17g2^bAu@%q+vFL=;w~Co zvRMGYht!jVOA%vZMFC@?O*#}177!3n;r1n*mTEEqJ@>Ujh%y&Gq}7# z{_KQA00M{qJ#cQ^!{L9!Aw=yz{eg{e2#5=4X{bNf-nkB}3#{|6Q+E-~tcfmroUF)p zWGBZxWczh(b36Op)>alo%XOi3$#t;@#(ST{k@TGL&1Y>3Qf6k7yiUC7;CQFhajUnb zb``eDJm_qDw7*x;@xeFuM*XdCbl?0wGPUpIQRSVKJ(~pP5`Mn*JvF%LU81^Y-u7X}(4eR^1{SvTCw48dA687roV3%P3QdI{l zH{@enRr1!WUx!XV8vYO;LkHeIcEf#6Jri@sab0aX<#jGcx#8gL34Mp@!V9{>mt51d zif?XvF_9DHlX>$_gwk-j>XE1;&;33`X5XKDw@?2;_RR;6?`+*wcKPg?O+IJN%-lI) z`CEV0S)aX2HR9RBGrwC7KdDU&(YhD;I^|9IOiMN7xm{!Gx*O&E{SOZoUi-PY5ynIE zALlL}*Y(*C%0yUGQCQVwLL3f-7hHt2Gvg1%?~||_7xQ9D0gDMgUu1t6JJT+o7pc6y zU10M^!5zgylxp5oiyZBuZMnt;;1O_`eraWj@7?v*sfe`svwXYiGAk#1$NbnUz&vr(?bwsT^+f|)!nSYiiIq?CbQ@1Tm#X)B zU7F0dEq~x@#4+)A2`f8gf*iMyoYV`}={-*0Yq`Zi?bHkXn#|ibTxOp-){ZpWe!g>c z`}E~|K?A2l7j7}BZd~^Z1udtw2$R(ew3J( zq5E{#o`K!#kZlIB?(w{61A`!C8!f*W|v7_^XPN(%QEfm zPc9xE&kV!=+$OZTCCu}9`(w~l7U``XFwWpyz0dO?&r`n_)@Q$XwCnEbc>XA7VSL1i z_hM)$##q7rPRQzkr{4EdQ%%1NYweA?PCcw25kEXnRN7(E?<^vw;6ymdJRPfi?#GcY zJFmDU7j`|XKI5ZzXno`?uCZf4_Y3+uI*0PbF%;HReYOA6oc#~KZ4ckcxZ(>(E=;d> zwmY&GSn5S)j{=wmBNMSkqCl4XR<4%r!We@Qn_nyt({M!O(W_I$yT(9t!Y$8%LRhSy zWv2GiUlMO^;Knc~#|)Fx^L_Kq`kA^{OErW5qHuOuYy*{6+aI7TTGDH}+~7v_NiBc# zi#}TGks5VlO7YE)+ZQ=+KKV^YyreKHEjjGMzu0j*LY;O9{=-JzBnM zoF=0BsVeHU;0-nNhAofKGha^c@p|6kdAn9&KMc9)(Cu&U9zT8@emv{s+h3P+vjCuP zFnE3a?U}dhXQsb>`_=Z=HA+SxvF)S2b4zGtZd7?r?hP7o-+7st){5IPIZNv}l1DW< zxLCG;)KfP|s%h9e_0nW##mn-d69QYW{5bVQ7zmg6?$%^5>l``~p+MW;*#Ie3jYJH$ zuM`0%&5y+KqqGNro`K*57Hs!sXMt0|1C2JP9`_HH1JA$UK3Nytq$tcMnH8RFMfW}` zo%M=~a(QjoG9;l%xEIdjsd!)Aa>m} z%o~r*?HxjhA~;4Pv&;iVq!Z`i8dX^YvIHkko7;QaZmB z*lHG$Zl!AxUcNEx9Y=_5q|$D2(b#(H6m%O&>U_u@ja}!iuH7%$B(mqzx8jc$2m?k8 zvXhTl(f&tQX!iyk#sQ6y`MyRE_nI~85uI6U8*xYyNp6i7j`+rtVQ$w$PO0y}nbwM7M-xtjelWIw{;O%++V>bh`R;sD&bra4GV zxV&n>L@u(*no8fVnX;H?+@>`#C0)W89X_);M#Lpwji1jTeI0#Vc)~=au=K>rY6(X1 z=#a%dc5CZ)si&{^$eYhQPdH!se10l!g-Ru9PABjx2ke|t2b2#*e!Xm5f8xSayEtuM zMB^vNPCt}Cq+M6|made*pe7m0zjkodT)(1Jc6pnn=0uuD#E-ZD5hB!K`^}KEQ#xzc z8Y)y??tQ>NeC%6WMN3P02{a_z@3g-1@kbaq78tIDiZaxUvZFXJ?n&3nciRP`>n78z zcFwl}Ce6y`p%B&hR@M&PSpR%hpsxk-_(9!^`(>oJ9`DP)*COqCXsvG2`;n+ZdLUts z;_ltMS{OorxG0Wh4utD0Nk46*3qa~+EX`G}wOrzl2vmkJCgqyB4O-lwQFiF`S<7#0 z--d6&z8!yZJ^NwBJE6G=$^%B-`mPoDr(qXwzK8X|EknpQmt!YwkA6Pn$V{cD?t0tx zW=f|7jywC5zr({yib`#^mTJqXNT@hfw*R;I{a06xZugtf{W&QJAR*R z_;p-WTIBGfIT}=npFs}ncF=8MRYDsy46qftQt_W4jjrA{L=WIyyyiLkBnH*0=>*PQ zdF#=$yMGyOa{WHHvTfI{huZVsN;6IiHog}zojANEusaJC?Ftw$#2|se_p}3e)-|zN zkwTUog2w^gReY(r7*hk1*oaeOLrp}f)jW62UyGkyk1W4Cadj3g|Kxd>0;Rj^MP{}80h=j;BQ+R>Ue$@P5puNDEKuL6k89sWFA%srqr@(15l{ZAnD`3 zvI1sfu2fsS*FPTarg@y~r^zt+sD71p=eOa`!z+tp49KZQV9ik3?|{*TT@|c--}9Is zy6ff4J05+2wAdO~0`EsuBQf4t>+)f@-1lpU)Ms?p>dd<3oG!pPo6xG?d}5lyJTcN2z78t*KTb zJds-K8JE*fHJV??&*;CuZltoQS_EQ`Z~L{-Q1QK>j$R)p$d7jU=9|J^+Z>x$?X{|2 zb;^AC6Q84RV(gf11!{w85vQUlAhW0Dh5J%zCzA*?$Jf4lYkc`LV zeBS-D@HL;Rzqj6D$44EO-%`>Dop2HDS|}GuUd{iQM#_@wK`qcCG_2tB)rG>U0+=1| zwgi$_E%}jacAu z*`rAe=>}a&%8g!ks#FRf=a+pl`WD}GpGGiIv^x!jv6}Oh&b$(R)kmOmF4Ui}@AXb# zuwS6B-(1M+!H5N8hh4FV2btvaOWV?~4I_8jeDvY19bs^11;k60N99xQ!4-{=noG)j z@12D6+7^Q3^o!m)G)Sc^Zo+p6VV$+wGgWHS0!ba>Omzs01zi%oC_%QO6k_Cv zao;azVL7}xQ+{d%wsQ$3SHpu6sr;lW7H})AxbL}M_&b^SPo{}-`STXyF%l+W3wc;u z7ORtwh{Iy75tL@08DoGGAaKuf_$amohV#u%?`%WQb6^G>0H_H=$}L-}C0N}UAO#d{ zqGqvL!yIW@2!-nypx2#5MOM3eR6kSKCMMb81=_RBz^WYZT9BXjP&HG?*mH_z@7Z>Hi`8?KIOReA@~<+SJwvB?%*fFX+o@8x;b zi-(}1{ZP9N_B8((xu)r!?TDCUVP<%=)3mB6JGOFMZ zoeR5rz2bo*w{KFsd%|dF#UN5T$rl3L9xS|zSw4IWcFL;ce%Q8s&xd^wk;V^VH;=BZ zMlTJCwlg9S5lh|Xx30O7XL3P$H zr{ZdYAaM-&eIM#R?;(vnU82S41!_cX^UQAV1-w`)lQ*6drR(b%^7Zgi*U7y2vV<^x z=ZInCX23`kQ(N5OE~Oj0T!Tc8YFks?FmJB;%eNnN6hq%{^LbMBg&;?SwjU#9i)7VM zI-t>vdlJ=Uck7S}Fo@}cU2eA)JZ%hbhQmHbii;0kw*Ax?sGgcXZeQ&%eF8svKp=f0A0w&ZCKTHJRf=8qE1r@=;wKrpju+#C)@HvtO40lN_c(5?Hnz7YX%I{QnJh)$1HFNh0No*zFj zLyT7t@y0{t4@=q68&pbPovPrh%=cwBV2m(W(=lCFxKD0+0<$z5TT%U_;>N2ikrt%` z6JtB^)A@(+B(A~dMp(kD^}?O&uXgzQ^>#S3+KdVJH3WAU`@B<+TKqa2dUXcM-^f;p zgV2-WljVJYSy*eRs7%~4GMN+BfC0txJ2`Yx_@(99qIk8>ASnLwtgx5&PP$iw%>}zt z!BH-fyGvF<@62Q zd4D@a$IAPj|I4uu4t~Juep|PZ?Uyk&SLyge&x#iXIk(E`756N{G?DzM%bC?D^uAC? znSG@!)RCT;!N-lHdH@#$DN~wvRt>_G;SJ@>qxr`I_}t6&7_b z2|rNTwN>MSCoq8@25;U8bt9dWnaNl`_h$M|Oso_M%{OzbkhIDrE8_W8J44|gjRWR%OJ{k-EVM5dK8R9I}djkv=5sOTSO4^DdY zc%=%I&@qkmWMil%g>A3mr0x}5Y&-k#8caxWRbIAaX#O!Jy4p^!xUaNrnsz-iJ=diEk|ynIQY|3*srNB+-V^2zAfXso-=Mk4Xg!5+`wT|` z@2sfkQpF3}+*HO3wuSOlFXT=@48Hvy7qmfyFDm{#iMrLhUmtH4C2=d;%=y^s^)2;B zFtqs&j+s*dAIkP~p)Cxkuha(LblgrhEJ6L;+-D+R8*TiS;rGP#_oiiDl>hwWQ~6UY zW|NTd5sD&Jti)a231pG8VQ4i>GNf5TpCqT%2F{n?7t% zHoSDmD}SC*CF)=w$JNBKJ92IJW(KDvTuj_gP37_Kp|bPX{4YGue2)&k*ZW`(|3aSB zbnB}*ndgV@JpA_NY11>2HdJWP`m2w34evMzrvPzTHkU|6M#))Uwq{`Mc9usEkUI}g zE)*VEJTWgxj0!uN;icZGlw0~GKNAi(PfL9MbtU5I`7iNR904F%3-s?}UO{8-8J@qV z6QjY3uhdmKbX`5;`meLt8Zh4WKB3Wlo3A>u&eJA8uHr?`)QR_w{#!sZW6^!;gRJU> zX-FgmN3YMD(h(IMZ)!>?qt9Tn6EW&jqT|*8x!FoJlM2}5B!Cgk<)#j-l@rfWogJ)m zFl4D679U^D#2Rpz-3oUjoq+M>-z=g!zXU{`;~l|Aq9R^OAw<#dYU060}&sD z_C9D4(@A5SVSnYEln=bVPxsY)lHOh$GbwOglR7;twZ6<3!K03x&K3>qvP^*}TR~KDE@Qd2A8TK!?~&2J z^;9+Y+>K)o<*)qb&7;rJjR6Z|_^a-yE(ITNztyXi4CM?I&JkD3fu&;6sqDT& z-xLGq^Al`2Lnus)DImh?;V}%N`51A|_QIMY0S2821a`tnOxi=3OvNiMUYS|?WnQKA zX#k%p2enLh957CSJ&|t2L-0(!CI=~zc{oW?9*`)URz2kUeAWJF@B7902cK6V`|M+5jpB7;`CCc0@mL_B232O36~{rr>#^)m z%I7VcLuyv~ehuILP9MB+@P7Wc2x|Lh!}Z^V?|1cmO|#pv?xEKcRN6bCOO?ullKCR^ zsoGG0EAV1~(zH>MgF(^|j1nh-LApoAeIcs>LJB$jg=BsgVZg(d3ieaWnZ|=VA+cf~uvFhV@}RO^J?Eq{%$g$_bS*-LO3}&M05*LiD$2 zeOe-qTCN0CB2@*;%^O1jA|%l!14)9$8LFi}mVQiZT)D6lv6qk@X4Lo0?D%Z_W52E& zPY&1Xw8J`ca|hw*Wv5uZ?nkW*zpUg3)t0QKSD67pH}dx9p{`>qCWY{?DHB?5O~kTe z+@6FZ^g$jQvqmw8Ftg*wZKQoMIA)6;x<3A$3pA(28d*ET9qOKMJ6DBC>f<&x2J4+{ z+UeS$(q7|E)@-uC-~pUFRe+C8(oS3-$g351Jvf)TKba@jfH6gRqJMLG&Y!!t%i#uG z%`;|Usj^pAToRdbblwe;W2hJs&CdAV`;MCx#sa^KK#Vte9SlC0oD>Lt)Wp~#z1_0* zGmTux5g#dTV07>pwN4a1;Ytp>U{7cB^`7=$wxv-=7o`QmMEm-1iU~3yB%Xd+6KVqS$U-BNTb*rf$B0Xy>o7k*9D|5ueiuOT$!8x z`FwWa=F#!ls3(1f&tt|uiVr(g`MXg7vLzkBq{j=%q(CbxD@{&Zo>Sv>08k!nWFM*)*q=O^ zWS@gv+uPDBJjsZ1kx23K#=MhVTen-P4a ze9|CPbbE-HJd#i&UEh2S-tw6##}4$0%adjlS88!8TO}V{Z%%mTCkc=DJ#NU3%wcKR zwHPAB?~bs{hYbq7jbgVS3E=CT0b(1)GU_b{`)0h5RjrhJFyc`X3VhMdkLXkN`Y<72 zXEJO)xdDKmPL%uS;n;}- z-Z^1BiQffE-$X^fNhbX0znU$PQ!bGh)u`=zM)P!Z>5BkQ=Ah}VbmI5l{l?QGqC$Np zCg^Ltg)286Bo)_j`f`Yv?v`u;A{K4)DV8bbr7hjygzB(PVN$Xmig)N(Kmi;OlYfDl zO4#KPBw+s`ltxqQ{fVzqq<^?&D}BNyziY53S%zNgrY~~wm?`+la%CWWGAK{Fx~F%M z8)UdTq2ypVS&x>Uup;%0`P+*airJ4QrS|aH$kyM#d((qUzb2CF*)V=ErIM`prD}sn z+B^Y>D3^iZ6lYhmqmIOHeI|SEJQ2(6XtRUHhVt>{ctu}K)*?EY)$n)Tu$yLAabi&o z1{R~%$}kN3`ZNDm55EShU(Nku`}y5V&HGg~p4V?qCHKD?>=(@V5jtZO(lWINY2(hFRkfZHd^`o;afGT|t<{cU4XFq2b6 z*!E{KfdU?fsRi^~v^G}Ix~x;MMk&RK|x$eW8+ zmnT$WD^2mea^_a`BbUsHka}wbF&PqKv0a$Q@F+o{I!O@b&XT@3%X}5qFLrk{#SR>ha}N$cumznYpfOBZhbH+3BRPxv)5eNx+@-F^qWc zKAc>sqvVPl(2zHQAHiwwPMvl!=TN}ss-Y>X+6azF00|@ljhfom&j4mLX z0iFo+QGgY~JpDprpB=xRjqp3IqsjoVvwCuLz+l(Nm&tg-{h+8Oy`fEOr;U6Dr&n1K zBH0u-=_=Dxg#m-6a0l?~tIFER-YKb*UDzP4^0q+UTpokf!_qL~1%h#e^2$^rkG<7s zY6=ZSLP-&(*d1Chs$cd9qlSx|lqNRg<#Z;d-1(!dL|LhkQu9Yr3eD%>zSD+nS}rlgpB%(OZX$pWmUYN;>G8bb@12*eE6D*Pjgwl zUOwD1_q{J{!IRR3KTICIU62uZy z$+d(S1{;fa83L5Z7BL6B?%@-O{+Kt9jNSqDqi_IQ$t8#Q5LzIbD6#JuJb@PIrTp3m z#M4cPj$_xSOa;wAK6Uq`|>Evc>B-PmvUEF{E;xbTQi|WQ$r*KgOVGVK35~aGw z7oMezqLDrwP-YR8!Z(8!DI!f)0y-y-H`cS8PmuY{ap*v`mll{_4JkN~qDVKhFRQm$ znZ%AgPHz;8B`FL7$5_sQ^;$Auv*kS1jSR{116CG_0e{oPCNVx}?JKNKre&8VVO%l$ z%G>8k!Ba+863xSMlyZ8+ny6kU%BuYQCQ@$Ei~8S~Z7*|ae%gFX7ANted}urUCQMG_ z@TBoPi$^FDW=;nEDA)u16K}}hFh5YkEWia7{Cj<@*hXR9Xni|)8Gx~dZR`5$rt5ex z+OPqeu5XJ;ey!$^dxqWTb*)3E<)VY#Z%h7qkHd7B(OH6GYKx@@xwURf3dmE@aYVxm zZ?c|2wrnUHYN;R1R&OydcdX7fs&?m<(NQ%X?(TU^HWw>BQrw~26BcZf73`JFtVIE0 z7Q%-W+?iIQJY!K)RV&Ks1Qv@GHnMnkAAnEMNWtw%j3zzA)hHC-(O9A9Z4-WD$)CL@ zj$~!>=OC;!yrmLX^s0Azmc0OW?Tc%}XKD)6Oy*`rcEnU`hMy@A(&4azMgv`EVpZqf zT=@MpY$f;i&4W{{4?kAUJ^gBRJTnr7$4?HP8g4f**!xAaS@VR3#-8Z~gT(`H!YkBM zCgEB^;|Vq{!97)P1`~cl>iivk8F&dvL7>Mff0CkczV{kantBt_cv0(Rmk?qzw|ImL zn(E0~g3Zh(=Z>6%R}9^SelY7;gafRO=Y8il6MEqXJ`Swff?=8Rz-Il1xp{ZdiTW80 zBf5K!X`*J3V?#eIxI7_;R^x^gp?2X>DgmTPrUuXEr)HsdHIs(mD;kJt^#eQc%U&;%zf&@KI%~cM+xw&>(PSlI7f^hGi0R!Uh zSA>E6Ck-dX1HTdzgV|SV^MV9_KunlwZA0B&AuWTZ3mu~hp&sNRQ^jYX>S{@kFHR|q z(;QILhHLJk+vPn@dY~LcS7@~!oCLJjqybLU&Gou|MR+ha^ZBEcwVF()KBBf982Lg5 zn^UM(*LbDUM55H;A}*v&e3AvhG3=|<*br@J1*{~Tgm*B9SnqE>mY%HUswm;Pwab0a z`ICTMFM(nYI-z(lD=F(L&I z$on!_Beh`xDh~h=f~_Cwt*+Pi-&<}*aJqmiv3f83k=t|kS8uLwhY!Fp zl}08)Kq|zcDO-z0vI;H(Lb}<_7~mo>DnF@V4Fnrl`%vpc3GC2HNRY1+fC6p@O%h~s z*AeGYUW3&%#fbCYHe(y1Dc=$XohzgSLPVl>i(_}y`V-o6+CiJI=LT8Tkek``;1&b1 zE||T&JyoP;He|>JkH^&r(%Z9{G)_8y7NOW^nj_-0k6-zf5)_|=`Hmk3EH$#qz# zc%OKAe!kgp+dJR$hbj(;I=_$#cC3B%y5hab0a*J-w2{Vv-Z)y8v^HB!$*j$PXC zyGKFXwXf9LDqY&Q3^O95B?TeS4d@~K=KLMnR73-oKAA&m=4kb>tb@!>&=_8YP03q=3YEWRTRnz9kYvuWhi8gb}G4ArZLE+UPD5P}Y=BZNfExiOJwPQ#z?r(uSda%n;|Dnqi&BBwT+sm51yNRu z<*oSGi&2{3cdGYIa8H8f@xsnv;PK62wJS+Pb))aer{C%vUJb+!U(#EP912KNt&UyZ zvWs^%wIaN*An*3k#^Vjwo9{fh|K!u67<})=Y*MlpChU@@=3OBo@zg0N&)Uy2zUsA} zp9hHh7=VT*n`^O+&qwFDnZstX0K#g-TV86e+A-czp~bZ|~_ zHo#q?-^B&BS0(J1)?NmDt+^el!WGX1HH{{}y$4&a*&^ML7tNSaP0aHOob&CeZ+EGk z3%Dwfh*oEKd(VbH`tB)R!W0gGUhzfkJee|?*pij3n@}gD?dpXXTKZGPSBBB@B zIv0*k)W8utg{^mdoh#Cy_5z8%{zJ)mol?+#Kd8`lpz_@%$AibLMP>`X6F==YjdOqg z*2$`)^iag^kuAftu$95#o!2U=-Yg{_{d8ZJy5r!d#FBkhW&y%p=Ncu*gPwSeA1WEL zMi<8K7X;`&yTm<^$~kp3^ZNEJj{~H)C%!`8$$j?@;O9$c5wqI4l{K+055i0}rBC&y zHTs&{KvnC_nMvm@MUo^HNH`nWdZrGo$+X$anM$mfg0g^1CnsGIKLyvoGePzraMSYk z`p)CIs;{5p6^7>4Zi|ViM}tf&DxY!3ef~__POg>%HwE`*R@4gC$ct1XPpg>?=uz+D zRJ!k_jypR?YR~{H0!Q6`p7KEL?g%WI>)MWG2z659tus1yzC%-W`9{kq=#wpZCg-v!rXYwGQ-^@f8x z9423G-+uPQu0mt*g(HB4l^1%G8w_hcvwM1brwnlAIpxLhY&t=wdn_-|`|2FH8#GsP zvFHYxR5!f@K$8J;egQ~uH=B+?km5*>?MYikvBD5rF|4HVzfXd6{n+qTzEUMk&DFtPB%edg>TomS6+=J_x2fntyOOGwr1fYz zaxLa#zmvAfQ&Z2vJqdkfyMgeVcb@A-ZraP&d3xfGSq!uanKA*xi#G}Ldw*8|en`eb zQs}5sDP}y z(MurDyxb+_YvwI*J=WUgjzPucsA`6LWf`iWi814as!mLB@0*#Ga5ii(J+WGwB3J8` zLZ>$n9SPbAWkKE6qF8r`K3s*Vwv`4quQX4?TgM8;QHE3t-{et%ZidJVLKsfRCHHWH zaJ{14y(s7QgoYaDRXMrb8veVT>ik*|x3DLei97@>M!#dirJy4Fgj2+1<9-uC=98Z$ zDqaHL-z+C6G#tL6UKM-Xu3Ukf9I-7Kc5MBm%LxeVQLP}R$_RE1T5OES<0mMOr79Tv z;U3$**Dx*T+XM?^1}en%-CpLmtQu>dyD4^rW+@wP8ncZy&%_XZ#Kj5;dl&Yd zBb8wvX88k)rai9cj?FMV`s|d}B|YR%K|U1rcS5$2NVQ=*S#a|E%dSDKN4_A>X5xBS zJwaQeTRti@SHNvh?Em7nELP9cc1R6Okgh>&(KD75iaq zb>4u9>a1-x4^>-nBQdfXndL%*DETb{A#&bOh= zI0WzobTF%}&>jia==X`q2G|ze`VkeAeIdS2fy&rw;dw4b3y>rAcuO(Cc#qOaRA!;- z8JkG5Y)R`(bxw`yH%soh0d!ATi&$^x^FH!QWlWIe{9yyo!}W3x6+3xydly2!gXmD* zqcq-)7nN^rxLT<>GiKpv?~1E&V{7uXT7r_%<|QY%GzbJ|9Y^kX#@g9!D#pGm%-~mk zOf+I!Loh^=jaPr8%)3{}PGeCtu{bA5TcUkg#ENv}@nSGG*)~f$msjRwSkb6meRja? zDNSKJd1u-)U#0kSVzc@O`*%FG^ex#jK{&i^zQ;%WhnA&Nss2eB{bts$skW!ThwG|7 zN*U^gZ?)x{{+`vVHiL`!+$Nv5J6yJX=1zwGs*n?EaYt2Tal_4%!_;OGjK0oNkG-;K zAQtB+Uhz;nw`oTvcqR@6X1yTCSCZ1K2knIgc!qK+bY~z=fZslW!>iPQLBMc$jA?=< z+>~|rlUKh}1zsQ)Sz0EjU2xGhR_8+86`60|snNcQ@!%KjGkHN^CN!9fHp|F&Q?#dQ zIZ-060`j5_YK%ZmV2^=gGm)Ait|&KBrR9Zes&uEsF{vuA?Y^e#TTiq!PyN=ig!eWs zHyOZff_1o3x!IvM2K>qKx1h1b9vXC2TM1ZFlWIo0o#JZ6@WZ6Hd&DF!^tH?^= zbup9mBP~GRBnw$=cnAP+(j}OSyS1dSd|oO5mPs>IhlSL4(Ou4~LV!g(KQsBYO|2*D zRj<)V_h9e&>XdND_cM$R3ri?`dt7mJ$wRDGJI_e~0C+8EuCzyTn|p&7C$-jH2bR`? ze$=FER2^mSTAN!=)n-iEF@@Uo$Y>x}uC9l$RPR!xkjVBou^z5CtBeqHr zBdKZ*>gPq(#8)&m30~cPv7cIY;^8KnG5vD#zA8N~#ry5~EgtB1MihwH`W@P5dGd|2 z{EZ!oj@w9GLj6iiL?fX~l6F-2Y0O2|zAq!?u>)^pZN#5uCV8n6e*?w4yY|;$)PZ2(Ii+Z?o?jr&J`ac;XAOpd)5hno^3%K%T zSx*U!i|qUpC&8_2g3%KEIsuH3>|7^VTG?7!THQXOmM^Dr_H1Y!s^*bac8Fbyf>O(M zTD{8;lNl>5!LtuGjk^cO#CCxzJU}GlqGx8RIH+X$wXmzjM)Ykpm8h=zpvk;BUw1|v znua5Z1=C1^jMPdNoXupFm{MdaWLM~L|sJD3#)%fL&>Z`vS0w3;>E&P=ccUg^|ZO@>cnSz#o-u4231n)*@ zz@id|w&dg!1LR!PA=OWGZ#2LbFof-;2evzJ|5Xg%*q`qPU!Du zBLxKN7pID}=;YdEiTQ0C8;M^gYP$x@$tmaL!a|_jol;LgBy-wQ+X`#x%?7n>bW1%sv?)#Qj8yjA z)J2(zt05D$i1X&f>A6PI)TUz%GhRM`dDW6q{XIYXjJpN7Gbow^X^v3 z&D>)(kXv?VaXqTm;oPXE65}x6T>Ce{jAT+n%JiM1@ms&%E|EWKdG{P8^a9@(CBC`H zeL*>exqL^u*4ESmZ|{`v52X(7xX23+>Y6Ug$qn2s`Kfmq_v2*#+uy%qj=X8v7TVSO zqDrLhKv&X>@ukqk)6;cIHvNY_FB?5BI`IM~O{kGQ+bX?VblA`}TOQ}r4r{_Zf339Z z)yE~i6k2@%nL^-dF&mmqQHtDXC>TFS_1nq)_O6uKadGYVC#{SN20y!;uP_h(ur>B- za5{SU@Y8gy;4X{W!awIQBta*LuES**;<9JP>YK{Ss10F593HicN59t1p{j}koqPtCR>tbnoGYG-(bSS@xNH6-+PgUq;8wQ!IpKg3cD z@9a+|*=s&~bE`u_Y?~PwU1o}4s&et3C>syNc$)u12W4nVfRF`Q8xF1UQpM;}?MN2= zzK4dGIGb)Ky&27nbX9!fr#1(glt_M`t+e@8HHy`PikC&EaBHh@Dn8h^hbdgSYH~J1 zH!vVvi*o^^pvkw-?`C$zJt{n_#-OopK>Frui}E}PsZ=RCpD+n2EqYT{GT_PxgU=Vdojg=OV8f6WibC4ebhr+(ndWbtsv!lRFl{Z>mBMK zyBO#4q?4(*L=DCk#!OXU1v~K2Au>6bvCzcm>9nq91oGsFCGJRVXzAd2YkdsX-JHzd zZPN|aBqqYnAeapTR#pZUHV9|5q%yYM1}-2gY{8V>JC9bD% zye-VSQ{W@t87|v-keL+Qae&gVoR|+J_yPQ8W_5&S1jh$zUWib`lOrmm{cb<%P z;teE}B3|8t|LZ~dmrAU8s_LEGI)F`xC;yn`GqEEGrW@fi4HTs=_Jt1ruoLJmcHT-` zoVru-V^YsL+v0miLOb&KEz|A>_DBS4SM4h%P8@uvv6| zt_-V5&(l0fuXVqql`8LBa{8G32aW7(wfej^iBNCvqK>le=$@bh|H~z8aA>ty;)Dy; zXDktuDw!+Qw*enZWX5mFd|1z>7Zi2V{VXB!!fpOqQ4|i})`<6-X8LQ52xwVAqe)vm zE7M=LJ|_BN5@6eY(ui{NQE~a{p9xv8{h;m-_g$oWzPPS&_roaX4;u&OC1pI^+Ci&d zSS*xIo}0$DK4Q4kAq=IeJe10Ng||o{{tE@uYtQfxTyB;Tr>p5iY#?g_5#Ub(;4UNC z@({SMzf4v3nIP~74r zb@7qqHV0R_2HH7gq(P~fHGkU+UDxusM5ni|zOEzY;m{*1+c}ucy3e=bOKm#&WBy0(Vplj5NhLH5yv|u?wSsIf9AR?at!fZ z6j-ps&oRPGJG%te+&X_Ez6ey@8)$zy zzyVN<0OLlJnl32dqj~X#Ij;fKI0$Eq>vJH~Qyy~{yAG?f9*E*#I^#9Oa|!e#fH&=T zeHFhU(0>tqH=$fE<4c;dRc`JYUXq!D9;OKz&sD3>+XP#;scu`PdXPfInR;8f|MRX& zb$bIsJpo_tXh&!=_K07gUWRyES_gcAQZXo;M7u!{L9vX=bp5MorsXu{q3K4uVX6cN zKQ0R0NZGNlCf!m(^JCQFzSVhnj=_{M0t2&WOAV0rH=FwU>Za(f_?b5Bn54~zx#8}l zVZuXjoZ4*GQwM_#xAP#5R@ROUvsaz5g={Yxm%FaC$Q3KK5XXUC5zafkuPjB-OMf1H zid)&Mh^3Y+JcUNT%Gu{%-QD=JV;v&v5&mVn>gLBYk8fyNzj;D-uzB8DbiwBokefv* zE_wI!A4c05{!*cyY&_bd{o(R4rk2gWmR8#Mh=l8oyr#THm;tX1*EJr9C` zebXuyz;PK^a`E0^S48>@xq^DBSQ3j=pf%Wv2p8hvn=18ovpWd@advPh5#a@rPqdbm zV2dLM4$_CC6liP!6d_BwYa1-CR39emWR^8#G~p5OWB!zp%&|vfyq%gV0)aHOANa_@ zw`_yYZ0$idiy`N2hEJWff95)dz18B(_iFrH3S=;%Z}#8h#9om5-?*CB_xxo(jx}(G zfzg>NV`uXE!`7EhclfDXI=6fdH@{=_>A@_;x7nP#y2V9>&3 zAX3U`h+kpFp@|4(wMN71SfP)!^X3qL1*qDI=~pA=YXyICFeTlUhJT9wlfk$rq3Z>~ zOZg2<3a-&$+xi6W4B0m%WntkVQBV;DscS%^`UeJRuEdTEkCvoJb_ERzS0H|Ri&KhR z6C4M*?IOkRIje%;%;Pauu<}pkk>xRqpYnhjVh}K_X-G~}{DP^09cy3$2(`;2}1*;rH`(}{npE0GMjds*(RUa z*tbGehlOC;QzJJoy?F1T4Sx9pn~v^qGN@IfTl*TF<#hCwO6bjMUXpP8}yun&ct2SQsntc(K{a4H`#)SCda;XN*qV4T7 zsv^x|@p_Erz6_3mZ^_Vht!-~9W^Mxl>RovQhlvJ+ou<<}im0ZJrnZj3#wH_sN1mpZ zHipNvERok_7|hC`Dr+kt*5Z`N<&LRf2Yx}`?dDbUmmKp53fyG6OTG-@jZPzYVu^eL zLu$!Wz^Lru@#%p1Qdgv#V#Tx~-xe#Bl5XG!x_S?bpAioX$ZAkck<$3s+2GN2m7%*^ za&<RlE2$Xq4s-->{=^qO+fgP+p(W4fCS zA&L&;TNKi;5)Jm?ZpN_xRc`FKNkuYjV;0ob<|Vy_;G#5*#DCCNIVNtdiRTgM3GV-~ zaQAlQ$%j!|H;THVZ(UH}1^+K?al|ZQn8$xA0-X6?!m@o8V`Ob><6zB9bnqOVbhNdx zXMQ?;WO8J{WH2O-ERRkKIgQ6GWTv@0UPokaXjbI!n~9n4a$a@FEHQoj(gyns0;HYG z#t0@L6>J4d!dtHUJW5ih5?>slz*@Hzdj|~nFo2@r50U)zRC#atg>?Vp<^{u%ifeR1Qv?BtQQwE>P>gg2LH%;dUq5G}Npt*{pHEs@Lu#Htf7)($yuN=Mb}>zO z?F39HYJ7u(*vfs!>|%UX*e9h2st*l*e~{^fRPET7xg=qMDEy?d zNyTMXUcD9B{Qi4AfQ44E>MGN+ae92U{A^^+DRJ?+Bat&v?79w4KELR6|HUUES;fyM za=8)9{vp9q>;|poKw5P*5;;q#mrsm)N#P+xIPyBL6jd6DRsOXj2x}ScJ(34sv_JLa z!sGrI&|0}dGfuxMiKDxe0N6*>Fu|$D@*`+OAos}nX#i&#_SpDQC~9?>`GNwku<3phfY=_!Mk>7i6!1q3_=JEgK zUB7Rr=U)Hh(>qzS;SzhhTfg&D$CrOSmy4ax5d!H4qDWY)fs>Bsxz|eOd=E)tf=91f@3iL zUiv*Tr}|f<=Y^c}LHskVcpimhe^T}sww~xJPO9@Wu&*NrLHPsmINs6v>_JhpD#w+c z2l=xej#|c*OjPipKfZmK zw?`X$yZBeHrR|%-bgd2NS3;Ki!^`V`Z*9a~d7HtlelgRb&iZ?Xr|<=`gm@g#2gYKA z;^>mMj2<^%002Lp6Hq{7Y$ezbbx=Dr7X1 zmq{I$8i)tqM&kT>6baRn)tRbZA zCt#~^d>=WG|ETmF9Ew}1ew}we{yt!7KzhM60Kk!$ z&E~u=^6HCSo@8;>zQAMSScUq=7p_z2EPs4u3lby(sPlc5tdzawt;K*5BK(ZyrZDtw z2f5zY6Nc|-{J$^hPmZ2_Qu3qW@Ri~w!0+<=m3YHLD8L^zzDK&)zHHyPp@wLZ63JBm zqpHYye`DUQL%zvH6{riV>tE;+XS}U;^15e|L<2wiYxl0DcI5u|)yUr%k@~XYzlSsz zhRO5vYq2k0Lxc?3<>+;X6|7^hv_aoe5!q)jSm#)M2cL>dE*FJCQI>a&2uP=yGSSRd zxc7Co@$9C7t*=K%@ASD?^i*ro_SU0Iq#lEMem!3fv4jcvjBoULmt4<{ADdufrPg`yBQeC=zf_o*r~b}1T#}XJ#yO~~RxGMB zwTx^0bFy@aNEf1N?e1yalX=PJ+FJ%iG7lOWe*H`It)8*eU19R&|5E_dJQdbx{iS9$0--C_P%#H$%Em*hg9NIVGK6r^?Cg<)Z%5|iYuc%EDENGEvw0nJ)6N7)YZpxIc-T!1?$2XTwP@p1 zglig!o!Dg1il8Zm6Du;jph0+RcW}FqgDR14Ah9%4jL5M-GUiE@MY6KQl*oAKzI*e| z>rRo(WjCYsLaRstO4-)^Ps`)iO1j_+-@izYB(ba5$tTfI!xb&6wKIc`M|mLA3wVmW z^2->B_^b&-V1r3ff({TN(C4fdeK9v_pTyr(+Gl4hvMYn+Je)10?bD;p^X6n zikbH|;cZsKZ6%L->M?KAn_fxV5V4c|m)a%Y?JZK0=El&5X|^pgHr?J;a16Yx#(>1DW9+S)a1O!lVq&i>Wy|VFLcKuqqLImi1id-tv` zcWO+2xr=vR6*k=0UAvO>eEjh2`>xQm=EoP_VPgu51oB4bR3FcEd-ztJSR2G3k2#yB z0dTckd}HgPY1GJeR%?Q*%f*K1^w>NR0JF@!hr5{z_oDbI0~&p=UN$wM(MgNzo=sx% zRJvElgjZkGOQzG;nW*mAH-lpt@s&9?YZdoPjUSn|f6^!`4Wq8oju%+ zyhom~zQ&hPE!Myp^Swk%-n6Oq-AZ^4{Tpj|=<}dMLHP7XkUg*R;sE=$18qJC&MS zX4o6Wxw_aT`$Ou#`uuI@kTNwKBp@#~`)Wuz?LEYp`t|lsf};xd+SU`jv(*|xztfqQ zUi$*Ei9{t@Bik0MUy+*f7&i4zR*s56tz?>#;&3C>O|YtNfXf7{LFS#JP-O{*brdCN z#wrg6YD+bRyKvW3kF+8rF)8f;+JovvmgE`e7ss(K#&b0aYk&)i;iJZ4;tZm~ygbOZ zzGvpA{64Pde)xsvk=T7Z#XFHYO-rvtGF1fGO_4?hT&Cy$;C(~oQy$RAKe;%WJue1v z4n6sx@ICI6Rz^n__Ia3#{xPoJSqBK;cSY#Hwg%L+W5q_fSiLEgyL+;i`^`k`6oO0b znEdhRGwO3!I~?rN&Q43Re$_^)RD3Y^`CU*dFjeNN2mpLT03|H|;>SsKQdG85%kjWa zljue)3b;mIcBZzWCpf1h+js*WAxvzVuD)mxcc@B#KpK7%eF#dndi|K`kx4; zvvQJuW-z0GwZm%LP&ecdd65y%beMyh3gn}z{6lJ;25q+IMkeCX`<0I_=nhtEn0nU3 zu34O*`839(8r4vmUP`-%H68V4wLeSGCcSQw4Lt1&jhbs5)&BNEr#vO?+L(WMY}w5d z<^FtcNuO+}6wpiY@NJeSgHeB@Gs*>5hXrq*yC<)k?S6%JSCck}YXCa&>OEPysU0L0 z8^*CBg)lX~Qf;`{`?(5!ah^mKlo}5U-5S!z81j>{P-R)Z_Ot5!Dbw4#3m+t|5p?8y zYF0MBUAg@6yz!fVUWJ&U$Zz3fhDOSgJ=8hX z6`7v=3{J7Wj2T)7HDQ&8>X^E2@GY}7#*@781%#2lU2pLrQ??*7^RY6!*m<8^<4wLC`QdQ?C` zyr2(RFXo=0f@6L0?1M?gjP3o6om{8Y{l|$01$lUfm$CQ!KXt6%@hRz;JaUOS&GyJD zOs^snGzD?u9^ECEnY~0J9FQIVj#z+(E_)NK9h0PZrM9i#(i-&4KBsQlXXWKN zI!@2c&hk6|^qfEH`+*a3hfNRx6-t{$=`{g^S#?+FNv1zcF~L7a#H|JlEvH=q@w{SU zG3Rfl5%?Em;t)|ecyUi8?58^mxFPe?goKswL`*+#C6K#5-gm#^RfGzZPq}NP?q!qz(w6W$jIJ8CEu9s17%bTIfU7|=U|K5L zuB`{}-4uv( zp2PM{QM|5bz_AffvxRW-drS4sy^ChYvOHEfi!w7aQBSL)p&;1*3J_T4l4BnK2@p&n z5(st=Ta!ML)4>_&oIPu1>3H7G-p27LmoY6iB@n+vA@gS2Y*FB;>@T zPmUVmamMiyC#B`(f-qH;N!Ihhe9*fb1pBEPz{zxqjs4M{ST547LFkU;(A&n&3u?CIH3m7km<#B4*>GxP7_yIJ0wBPJ={*#5HlXoKDY5V(B z=4&k#t5@q}&tw-q*%qdNx@Fi4{fv~;lTG8;U$l==i&2`li#8tD)O;?Ew1Awrd}gTcb?VEEC;-1F6#cRcOg-J4bXGzA9? zrMhfBx=xwgEySQND7O|&gu)?_Wsg&b{m%vcJR9o%Oo?59$Liojd)ynLmP|l7zo3h> z4=fm~uudU(#QEwdvem&$iW*sqiOp4;M{k|tSIjV*h}0;J1;Dx|*#p>CvY#ete7%2a zp-)%J;>5FzJ<-Gd&y;F832;hwCXm|1{3=leF>^m5mEWp`m&5{Kr;7p;2Ufy+&|<07 z_kkcG6_b%mAJ$l4oZPp?KX%&b{R+B)3s%ny4dno(wUPO)%iR3j5_5PGU3voB(_JCZ z;ntIF7?G9O9h^RPx~{o#w-bJU0C8@;QRB-Ed$%bF9s4rPN;9 zYj@`I{F>pitd3=DaKp^s1V~v9jT{3Of*z?y)TuMbCbek$JO_CyyL}$P{=8h(^;%2& zyv-^_W`L6$*UNZw5(L#_k0kN$q@=<6f2E?X_Jyj6I~rhrfS@Kh$8f4~mwc7CK(`%u zYZ*x4q`(LKGy-8SPDp!G@6mbUO8f{NXRehyq$c`(t6d2Ya%JBOvh@15YMUIdYxS{l zb4IQn_x5)}>HC}a&r>Qzz}CR66J7kbSNR58p)Sr!f<l+`EAO5tj-~g;AUKY z3L%tSYI~!2!YuI9S3Tc+dt1?bLDz;yi8q!#AJ27A0RDh+Kl<%bJ06=qDN6TqDqd$W z>_h*m>EXngpg!BSyY{0|FoesMfSf)#FG0*(-nvlJsB(Mqbf?~GK5wbT`sJ*nA1N0^ zxmeHF_nTzxB0zYDA0l)&4@{QhExTK+63 zCzDg{qYNqT#asA)H~36kG_riDPO%TZtOuXi8o8?fd)E{LsgSxHeTLT|+8^fMCN_RG zNUPwd^6@`^taK1JHI)kDN^BQD(l^OU2^#5MU1-?BU?VUVfz37sL0wlH@N zo>%O3e9pQ(8R3aw`k1sd3@oc;{l`${;5X6p7MFDN&y`z0`;7U#dR6`DiM!>UALpeI zmEQi?=9q$!`|Rnu7Yp|8p1fkeXB~SPE!Jz>YP{OxZG9}zrrn#f9xY3){(>LX)RI?s z4Vi?bI*L{+@IIC*aJ=Q*yhj)v;pdXSM)==4-8^2tfa zj@HxmUL*+HWb{rlXNO<5HYdKKlwv zV`OW~{o3lnX{#H+!Hx*!4;iTXunc}!ki6kfWj^*b!4!!UeQulwwHyr`#O^WMN8jkV z$(Fe~GE)*$xhu%mW}vzhv6OCNpw~4H!d_b-W64NLrrv#318o4h3ghw z%fxO>H~O?S%7fH}AO+C(xP(QwofnD5m!ceUKE5)KsdY6W2Id)`u)ODT@!=~UvR6~S zW-ecn0iCNq6=T<(;ZVjQYdr5lLm2x~@)FCwcLl)MXB0t1H3@R1Avavi58pa4Ldk^W zA}f>n6U{m`IV|9bQu2!XgdkOQLhJ6)1WELVrR&B{a98)iLA%P$w}NfTd1J{F=Oj)) zIsbD97vn^I6Gs`DOQP~ADv*wm*WP0D@{|MHt@GvH-D^w}JAt9D2W>KHHpC|NLN@gz z?|@Uky|=K4Lh+h%BuP~{WjdMhm=3=dEk75$=84t)5%%~VihII*KpKE^^!)%4F>$z= zEoKc0K*6v+&_Al0$w(nDgl)4%jc?;vs+xo#;*xIO=et+F)i~Tde!`s1$x zUh?S|yT`9@oM9E01+d~k#&rZ3@4psaGB0mB2?7sgjSxC@m~mh%_5z*6GuoQ@dc0e) zHm<8M)y7Y{377e;P}d?}QH%mYp%dc*u6~eYEqf`&x_}n*ifxQse-h2WDXfim9_E(v}j*X|eSpCDP*79%C=4RmZjie?;s(GZO* zNP9M0@n2OTZaF~TJc0z}RXuyANhvD5mNd)uBlLa48u7{~ONtpT&pl0P6v;uMm`Id~ zN#~bAIRNwFW;8yw_?2lZLA6udC_wx)M0FbLq613Sd-UvAR=umIRwIj#bll2R0_F9W zM}8C`hG6!A9DG&X=&ieYOH9vhGRX1$+o(4x6{}2laFtaZf9HPqIWf}?T~%%hb0in# zEy@;1{P~5rzZ2X?;sE**+aH5_n5E%A>Rvi>^uEDByW0xyMxosM0APVTTR~>2QAaa8 zlqi0HqpPe zmWg-%^G1GJw)=bL{>x{FQ8!fc_J)Aag=yP8e~2Og2ChwAw+3sHnVS}7W>O3D3p89D*@v)p#;s+{_5^KZ7~19|$pjtot)eaG z93dq}ws`hEUS_kcAP%x8ITXQ5S{ebI%+O*>VgqbkXKc233{2xzl+UMv>pCAMH>4W8 znss$B=IG?PrN9cU^(|b!_4H-02k&a>iKmdAUzIt^aVbh{w^u;hf%S8-!b3cKA6bv9@WaE={%paQ~1C+}) zRcKO=4_tBy%6`ah*@I-sW5OqN%I;KVHf}9%oXEB!2W<~y-NZfGmquj*H|HJQyd(vh zWmD4>8S35u6V0V>Ra~sEs!}w?sSHCU=}z_PPQz6C2+g%^#I=^$U6V>Cwv{;rH@_;B z%iOI`{?d@TEhv>4a%rM=yL$`#tE)V*e&U%j0+NHSkDHdy^p303Y*ds10E7et#bqcE zKG7jXu}U^T6XEQM3D`!VBm-F-3U!{tZNDyEQ89tsSxRq?j((mUA~c>>)9YWQP)`8t zHi}<#p?hIOuc$Icva!vU5 zs_8GK&b=mjkO0aHh95VjLC?Jf0QMa24y!m$6Y}NRO~d$Wn_px}C}b?lqBtzy0ZD`3 z*L)aW0)8?XWRvRxRpMW6-lV{+oaZBb`(Nc-w+Qszx^Vr&${e!J`jJl?u(kR0#+U29 zR=V{2_s4V;xQhZwm)iH0F8U{| zo}$4w=%s5*;BtJy(F^XaJ@q$X>!QiJODz18PqC8pJ3X!3kb`;#MndgI&%Cghd=0!$ zZVZBk2UiKQ{*uyH0WbWS!sm^_b}0DWq}@c#xepsM=+U%_DBV}NLrT{id;+pi;V z!+-N5%zuB3Kp|P? zD8H05W1a3UviDmW>F`gd?D$1h$7gM|JoN&65nQ*p^_h_^ppWC%i$5)+W0%lsIoyNK zmIzK|Vz?=xDO`Z%XtnQphR<%!NKEfzaP zP>oIB!y-heqTYVT?V?!t1o2^=SBR#5N)Dv|#^sE2*dO!k;G;Y?m-5mSP2S$E=C^K7 zcKW{y8|bvULE=l`-}W9y0;w7hQes(v0Z8n(lDQQw?k|W22b43kCoh<-N-cd5B)1sg zU=IH?N8{!VE7o6zIVV?cxb=_!1+fGe(*+p;%8dEstW0@1H~=B_b?#5p`Jb6AnH2bS z`0mfGm?C}*bz@}j=fXEt&AY1eE9$Rz_Z2S#`p@G(fB<;kEzkKU@>gyk(l>icmL+yWl_t>xh&cAh6 z=Fu4e(L*Gxa@4XkPW%xnKR@E6oRe#j!R<)(@&`ZgFwD{8qyryC#3X zz*+as(a6WY&d^tv$fFM6;NXd$DH^Y@Ze}iisagK;E4T`;`>c?E8yWz&hW+)tv}A~j znm%h+!}u_p_mW@h&(fczwSzww0tGiay(vXk(RVq@G*G25&cW{JSZ6)>hZLMIDhl-N6}cb&`#b4F z{991S@Q