From 303272319af92f7bef2437b88792a18c207e5953 Mon Sep 17 00:00:00 2001 From: arsserpentarium <32496644+arsserpentarium@users.noreply.github.com> Date: Mon, 26 Mar 2018 19:01:34 +0300 Subject: [PATCH 1/2] [READY]pathfinding circuitry upgrade (#36398) * all in one * fixfixfix * uhhhh * demuxdemuxdemuxdemux * wire eriw * icon noci * tihsxifixshit * rewopower * fixif * screeneercs * returnruter --- code/__HELPERS/AStar.dm | 16 +- code/controllers/subsystem/pathfinder.dm | 34 ++-- .../subsystem/processing/circuit.dm | 2 +- code/datums/components/material_container.dm | 24 +++ code/game/objects/structures/plasticflaps.dm | 4 +- .../integrated_electronics/core/assemblies.dm | 9 +- .../integrated_electronics/passive/power.dm | 8 +- .../subtypes/converters.dm | 2 +- .../subtypes/data_transfer.dm | 21 ++- .../integrated_electronics/subtypes/input.dm | 154 ++++++++++++++-- .../integrated_electronics/subtypes/logic.dm | 5 - .../subtypes/manipulation.dm | 170 ++++++++++++++++-- .../integrated_electronics/subtypes/output.dm | 4 +- .../integrated_electronics/subtypes/smart.dm | 97 +++++++++- .../obj/assemblies/electronic_components.dmi | Bin 22954 -> 22822 bytes 15 files changed, 482 insertions(+), 68 deletions(-) diff --git a/code/__HELPERS/AStar.dm b/code/__HELPERS/AStar.dm index 7de6ef522a..c038e2e2e2 100644 --- a/code/__HELPERS/AStar.dm +++ b/code/__HELPERS/AStar.dm @@ -75,16 +75,26 @@ Actual Adjacent procs : //wrapper that returns an empty list if A* failed to find a path /proc/get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) - var/l = SSpathfinder.getfree(caller) + var/l = SSpathfinder.mobs.getfree(caller) while(!l) stoplag(3) - l = SSpathfinder.getfree(caller) + l = SSpathfinder.mobs.getfree(caller) var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) - SSpathfinder.found(l) + SSpathfinder.mobs.found(l) if(!path) path = list() + return path +/proc/cir_get_path_to(caller, end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) + var/l = SSpathfinder.circuits.getfree(caller) + while(!l) + stoplag(3) + l = SSpathfinder.circuits.getfree(caller) + var/list/path = AStar(caller, end, dist, maxnodes, maxnodedepth, mintargetdist, adjacent,id, exclude, simulated_only) + SSpathfinder.circuits.found(l) + if(!path) + path = list() return path /proc/AStar(caller, _end, dist, maxnodes, maxnodedepth = 30, mintargetdist, adjacent = /turf/proc/reachableTurftest, id=null, turf/exclude=null, simulated_only = 1) diff --git a/code/controllers/subsystem/pathfinder.dm b/code/controllers/subsystem/pathfinder.dm index 2cd52a4da1..fe503b0b7a 100644 --- a/code/controllers/subsystem/pathfinder.dm +++ b/code/controllers/subsystem/pathfinder.dm @@ -2,39 +2,47 @@ SUBSYSTEM_DEF(pathfinder) name = "pathfinder" init_order = INIT_ORDER_PATH flags = SS_NO_FIRE - var/lcount = 10 - var/run - var/free - var/list/flow + var/datum/flowcache/mobs + var/datum/flowcache/circuits var/static/space_type_cache /datum/controller/subsystem/pathfinder/Initialize() space_type_cache = typecacheof(/turf/open/space) - run = 0 - free = 1 - flow = new() - flow.len=lcount - + mobs = new(10) + circuits = new(3) return ..() -/datum/controller/subsystem/pathfinder/proc/getfree(atom/M) +/datum/flowcache + var/lcount + var/run + var/free + var/list/flow + +/datum/flowcache/New(var/n) + .=..() + lcount = n + run = 0 + free = 1 + flow = new/list(lcount) + +/datum/flowcache/proc/getfree(atom/M) if(run < lcount) run += 1 while(flow[free]) CHECK_TICK free = (free % lcount) + 1 - var/t = addtimer(CALLBACK(SSpathfinder, /datum/controller/subsystem/pathfinder.proc/toolong, free), 150, TIMER_STOPPABLE) + var/t = addtimer(CALLBACK(src, /datum/flowcache.proc/toolong, free), 150, TIMER_STOPPABLE) flow[free] = t flow[t] = M return free else return 0 -/datum/controller/subsystem/pathfinder/proc/toolong(l) +/datum/flowcache/proc/toolong(l) log_game("Pathfinder route took longer than 150 ticks, src bot [flow[flow[l]]]") found(l) -/datum/controller/subsystem/pathfinder/proc/found(l) +/datum/flowcache/proc/found(l) deltimer(flow[l]) flow[l] = null run -= 1 diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm index 9fc3683266..e5b4791907 100644 --- a/code/controllers/subsystem/processing/circuit.dm +++ b/code/controllers/subsystem/processing/circuit.dm @@ -15,7 +15,7 @@ PROCESSING_SUBSYSTEM_DEF(circuit) var/cost_multiplier = MINERAL_MATERIAL_AMOUNT / 10 // Each circuit cost unit is 200cm3 /datum/controller/subsystem/processing/circuit/Initialize(start_timeofday) - SScircuit.cipherkey = random_string(2000+rand(0,10), GLOB.alphabet) + SScircuit.cipherkey = uppertext(random_string(2000+rand(0,10), GLOB.alphabet)) circuits_init() return ..() diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index 7681b5491b..6f4e8d586d 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -194,6 +194,30 @@ return amt return FALSE +/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, id) + if((amt==0)||(!T)||(!id)) + return FALSE + if(amt<0) + return T.transer_amt_to(src, -amt, id) + var/datum/material/M = materials[id] + + if(M) + var/tr = min(amt, M.amount,T.can_insert_amount(amt, id)) + if(tr) + use_amount_type(tr, id) + T.insert_amount(tr, id) + return tr + return FALSE + +/datum/component/material_container/proc/can_insert_amount(amt, id) + if(amt && id) + var/datum/material/M = materials[id] + if(M) + if((total_amount + amt) <= max_amount) + return amt + else + return (max_amount-total_amount) + /datum/component/material_container/proc/can_use_amount(amt, id, list/mats) if(amt && id) var/datum/material/M = materials[id] diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 6815d60e88..7143459fe2 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -58,7 +58,9 @@ var/mob/living/M = caller if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY) return 0 - + var/atom/movable/M = caller + if(M && M.pulling) + return CanAStarPass(ID, to_dir, M.pulling) return 1 //diseases, stings, etc can pass /obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index e62e26d576..0a70774847 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -22,13 +22,14 @@ var/charge_delay = 4 var/use_cyborg_cell = TRUE var/ext_next_use = 0 - var/atom/movable/collw + var/atom/collw var/allowed_circuit_action_flags = IC_ACTION_COMBAT | IC_ACTION_LONG_RANGE //which circuit flags are allowed var/combat_circuits = 0 //number of combat cicuits in the assembly, used for diagnostic hud var/long_range_circuits = 0 //number of long range cicuits in the assembly, used for diagnostic hud var/prefered_hud_icon = "hudstat" // Used by the AR circuit to change the hud icon. hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays max_integrity = 50 + pass_flags = 0 armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) anchored = FALSE var/can_anchor = TRUE @@ -62,9 +63,9 @@ /obj/item/device/electronic_assembly/proc/check_interactivity(mob/user) return user.canUseTopic(src, BE_CLOSE) -/obj/item/device/electronic_assembly/CollidedWith(atom/movable/AM) +/obj/item/device/electronic_assembly/Collide(atom/AM) collw = AM - ..() + .=..() /obj/item/device/electronic_assembly/Initialize() .=..() @@ -501,10 +502,10 @@ IC.ext_moved(oldLoc, dir) /obj/item/device/electronic_assembly/stop_pulling() - ..() for(var/I in assembly_components) var/obj/item/integrated_circuit/IC = I IC.stop_pulling() + ..() // Returns the object that is supposed to be used in attack messages, location checks, etc. diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 186a2df257..859c8910f3 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -94,7 +94,7 @@ complexity = 4 inputs = list() outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF) - activators = list() + activators = list("push ref" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/volume = 60 var/list/fuel = list("plasma" = 50000, "welding_fuel" = 15000, "carbon" = 10000, "ethanol" = 10000, "nutriment" = 8000) @@ -125,7 +125,7 @@ if(lfwb) if(B && B.data["cloneable"]) var/mob/M = B.data["donor"] - if(M && M.stat != DEAD && M.client) + if(M && (M.stat != DEAD) && (M.client)) bp = 500000 if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > bp) if(reagents.remove_reagent("blood", 1)) @@ -134,3 +134,7 @@ if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I]) if(reagents.remove_reagent(I, 1)) assembly.give_power(fuel[I]*multi) + +/obj/item/integrated_circuit/passive/power/chemical_cell/do_work() + set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) + push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm index 23895d7023..5f7dd24ad9 100644 --- a/code/modules/integrated_electronics/subtypes/converters.dm +++ b/code/modules/integrated_electronics/subtypes/converters.dm @@ -293,7 +293,7 @@ /obj/item/integrated_circuit/converter/abs_to_rel_coords name = "abs to rel coordinate converter" desc = "Easily convert absolute coordinates to relative coordinates with this." - complexity = 4 + complexity = 1 inputs = list( "X1" = IC_PINTYPE_NUMBER, "Y1" = IC_PINTYPE_NUMBER, diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/code/modules/integrated_electronics/subtypes/data_transfer.dm index a769a16768..481360f6cf 100644 --- a/code/modules/integrated_electronics/subtypes/data_transfer.dm +++ b/code/modules/integrated_electronics/subtypes/data_transfer.dm @@ -75,8 +75,10 @@ /obj/item/integrated_circuit/transfer/demultiplexer/do_work() var/output_index = get_pin_data(IC_INPUT, 1) - for(var/i = 1 to outputs.len) - set_pin_data(IC_OUTPUT, i, i == output_index ? get_pin_data(IC_INPUT, 2) : null) + if(!isnull(output_index) && (output_index >= 1 && output_index <= outputs.len)) + var/datum/integrated_io/O = outputs[output_index] + O.data = get_pin_data(IC_INPUT, 2) + O.push_data() activate_pin(2) @@ -141,4 +143,17 @@ name = "sixteen pulse demultiplexer" icon_state = "dmux16" w_class = WEIGHT_CLASS_SMALL - number_of_pins = 16 \ No newline at end of file + number_of_pins = 16 + +/obj/item/integrated_circuit/transfer/wire_node + name = "wire node" + desc = "Just wire node to make wiring more easy.Transfer pulse from in to out." + icon_state = "wire_node" + activators = list("pulse in" = IC_PINTYPE_PULSE_IN, "pulse out" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + power_draw_per_use = 0 + complexity = 0 + size = 0.1 + +/obj/item/integrated_circuit/transfer/wire_node/do_work() + activate_pin(2) \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index c666f05d88..6ad3fc9797 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -344,13 +344,92 @@ else activate_pin(3) +/obj/item/integrated_circuit/input/turfpoint + name = "Tile pointer" + desc = "This circuit will get tile ref with given relative coorinates." + extended_desc = "If the machine cannot see the target, it will not be able to calculate the correct direction.\ + This circuit is working only in assembly." + icon_state = "numberpad" + complexity = 5 + inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER) + outputs = list("tile" = IC_PINTYPE_REF) + activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + +/obj/item/integrated_circuit/input/turfpoint/do_work() + if(!assembly) + activate_pin(3) + return + var/turf/T = get_turf(assembly) + var/target_x = CLAMP(get_pin_data(IC_INPUT, 1) - assembly.x, 0, world.maxx) + var/target_y = CLAMP(get_pin_data(IC_INPUT, 2) - assembly.y, 0, world.maxy) + var/turf/A = locate(target_x, target_y, T.z) + set_pin_data(IC_OUTPUT, 1, null) + if(!A||!(A in view(T))) + activate_pin(3) + return + else + set_pin_data(IC_OUTPUT, 1, WEAKREF(A)) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/input/turfscan + name = "tile analyzer" + desc = "This machine vision system can analyze contents of desired tile.And can read letters on floor." + icon_state = "video_camera" + complexity = 5 + inputs = list( + "target" = IC_PINTYPE_REF + ) + outputs = list( + "located ref" = IC_PINTYPE_LIST, + "Written letters" = IC_PINTYPE_STRING + ) + activators = list( + "scan" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT, + "not scanned" = IC_PINTYPE_PULSE_OUT + ) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + cooldown_per_use = 10 + +/obj/item/integrated_circuit/input/turfscan/do_work() + var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom) + var/turf/T = get_turf(src) + var/turf/E = get_turf(H) + if(!istype(H)) //Invalid input + return + + if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. + var/list/cont = new() + if(E.contents.len) + for(var/i = 1 to E.contents.len) + var/atom/U = E.contents[i] + cont += WEAKREF(U) + set_pin_data(IC_OUTPUT, 1, cont) + var/list/St = new() + for(var/obj/effect/decal/cleanable/crayon/I in E.contents) + St.Add(I.icon_state) + if(St.len) + set_pin_data(IC_OUTPUT, 2, jointext(St, ",", 1, 0)) + push_data() + activate_pin(2) + else + activate_pin(3) + /obj/item/integrated_circuit/input/local_locator name = "local locator" desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ that is holding the machine containing it." inputs = list() - outputs = list("located ref") - activators = list("locate" = IC_PINTYPE_PULSE_IN) + outputs = list("located ref" = IC_PINTYPE_REF, + "is ground" = IC_PINTYPE_BOOLEAN, + "is creature" = IC_PINTYPE_BOOLEAN) + activators = list("locate" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT + ) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 20 @@ -358,10 +437,11 @@ var/datum/integrated_io/O = outputs[1] O.data = null if(assembly) - if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. - O.data = WEAKREF(assembly.loc) - - O.push_data() + O.data = WEAKREF(assembly.loc) + set_pin_data(IC_OUTPUT, 2, isturf(assembly.loc)) + set_pin_data(IC_OUTPUT, 3, ismob(assembly.loc)) + push_data() + activate_pin(2) /obj/item/integrated_circuit/input/adjacent_locator name = "adjacent locator" @@ -800,7 +880,8 @@ "cell charge" = IC_PINTYPE_NUMBER, "max charge" = IC_PINTYPE_NUMBER, "percentage" = IC_PINTYPE_NUMBER, - "refference to assembly" = IC_PINTYPE_REF + "refference to assembly" = IC_PINTYPE_REF, + "refference to cell" = IC_PINTYPE_REF ) activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH @@ -810,13 +891,15 @@ set_pin_data(IC_OUTPUT, 1, null) set_pin_data(IC_OUTPUT, 2, null) set_pin_data(IC_OUTPUT, 3, null) - set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly)) + set_pin_data(IC_OUTPUT, 4, null) + set_pin_data(IC_OUTPUT, 5, null) if(assembly) + set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly)) if(assembly.battery) - set_pin_data(IC_OUTPUT, 1, assembly.battery.charge) set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge) set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge) + set_pin_data(IC_OUTPUT, 5, WEAKREF(assembly.battery)) push_data() activate_pin(2) @@ -851,8 +934,8 @@ set_pin_data(IC_OUTPUT, 1, C.charge) set_pin_data(IC_OUTPUT, 2, C.maxcharge) set_pin_data(IC_OUTPUT, 3, C.percent()) - activate_pin(2) push_data() + activate_pin(2) return /obj/item/integrated_circuit/input/ntnetsc @@ -891,3 +974,54 @@ set_pin_data(IC_OUTPUT, 1, null) push_data() activate_pin(3) + +/obj/item/integrated_circuit/input/matscan + name = "material scaner" + desc = "It's special module, designed to get information about material containers of different machinery.\ + Like ORM, lathes, etc." + icon_state = "video_camera" + complexity = 6 + inputs = list( + "target" = IC_PINTYPE_REF + ) + outputs = list( + "Metal" = IC_PINTYPE_NUMBER, + "Glass" = IC_PINTYPE_NUMBER, + "Silver" = IC_PINTYPE_NUMBER, + "Gold" = IC_PINTYPE_NUMBER, + "Diamond" = IC_PINTYPE_NUMBER, + "Solid Plasma" = IC_PINTYPE_NUMBER, + "Uranium" = IC_PINTYPE_NUMBER, + "Bananium" = IC_PINTYPE_NUMBER, + "Titanium" = IC_PINTYPE_NUMBER, + "Bluespace Mesh" = IC_PINTYPE_NUMBER, + "Biomass" = IC_PINTYPE_NUMBER, + ) + activators = list( + "scan" = IC_PINTYPE_PULSE_IN, + "on scanned" = IC_PINTYPE_PULSE_OUT, + "not scanned" = IC_PINTYPE_PULSE_OUT + ) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + var/list/mtypes = list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE, MAT_BIOMASS) + + +/obj/item/integrated_circuit/input/matscan/do_work() + var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + var/turf/T = get_turf(src) + GET_COMPONENT_FROM(mt, /datum/component/material_container, H) + if(!mt) //Invalid input + return + if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see. + for(var/I in 1 to mtypes.len) + var/datum/material/M = mt.materials[mtypes[I]] + if(M) + set_pin_data(IC_OUTPUT, I, M.amount) + else + set_pin_data(IC_OUTPUT, I, null) + push_data() + activate_pin(2) + else + activate_pin(3) + diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm index f8e858ef94..702ab588c5 100644 --- a/code/modules/integrated_electronics/subtypes/logic.dm +++ b/code/modules/integrated_electronics/subtypes/logic.dm @@ -16,7 +16,6 @@ activators = list("compare" = IC_PINTYPE_PULSE_IN, "on true result" = IC_PINTYPE_PULSE_OUT, "on false result" = IC_PINTYPE_PULSE_OUT) /obj/item/integrated_circuit/logic/binary/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] @@ -36,7 +35,6 @@ activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT) /obj/item/integrated_circuit/logic/unary/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/O = outputs[1] O.data = do_check(A) ? TRUE : FALSE @@ -66,7 +64,6 @@ var/lstate=FALSE /obj/item/integrated_circuit/logic/binary/jklatch/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] @@ -98,7 +95,6 @@ var/lstate=FALSE /obj/item/integrated_circuit/logic/binary/rslatch/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] @@ -128,7 +124,6 @@ var/lstate=FALSE /obj/item/integrated_circuit/logic/binary/gdlatch/do_work() - pull_data() var/datum/integrated_io/A = inputs[1] var/datum/integrated_io/B = inputs[2] var/datum/integrated_io/O = outputs[1] diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index b30500fad4..b6b83b8469 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -101,7 +101,6 @@ shootAt(locate(target_x, target_y, T.z)) /obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target) - var/turf/T = get_turf(src) var/turf/U = target if(!istype(T) || !istype(U)) @@ -123,8 +122,6 @@ else A = new lethal_projectile(T) playsound(loc, lethal_projectile_sound, 75, 1) - - installed_gun.cell.use(shot.e_cost) //Shooting Code: A.preparePixelProjectile(target, src) @@ -139,7 +136,7 @@ Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ being held, or anchored in some way. It should be noted that the ability to move is dependant on the type of assembly that this circuit inhabits." w_class = WEIGHT_CLASS_SMALL - complexity = 20 + complexity = 10 cooldown_per_use = 8 ext_cooldown = 1 inputs = list("direction" = IC_PINTYPE_DIR) @@ -163,6 +160,7 @@ return else set_pin_data(IC_OUTPUT, 1, WEAKREF(assembly.collw)) + push_data() activate_pin(3) return FALSE return FALSE @@ -314,6 +312,7 @@ spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 50 var/max_items = 10 + /obj/item/integrated_circuit/manipulation/grabber/do_work() var/max_w_class = assembly.w_class var/atom/movable/acting_object = get_object() @@ -370,34 +369,49 @@ size = 3 cooldown_per_use = 5 complexity = 10 - inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_INDEX) + inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_INDEX,"dir" = IC_PINTYPE_DIR) outputs = list("is pulling" = IC_PINTYPE_BOOLEAN) - activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT,"released" = IC_PINTYPE_PULSE_OUT) + activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT,"released" = IC_PINTYPE_PULSE_OUT,"pull to dir" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 50 ext_cooldown = 1 var/max_grab = GRAB_PASSIVE -/obj/item/integrated_circuit/manipulation/claw/do_work() +/obj/item/integrated_circuit/manipulation/claw/do_work(ord) var/obj/acting_object = get_object() var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) var/mode = get_pin_data(IC_INPUT, 2) - mode = CLAMP(mode, GRAB_PASSIVE, max_grab) - if(AM) - if(check_target(AM, exclude_contents = TRUE)) - acting_object.start_pulling(AM,mode) + switch(ord) + if(1) + mode = CLAMP(mode, GRAB_PASSIVE, max_grab) + if(AM) + if(check_target(AM, exclude_contents = TRUE)) + acting_object.start_pulling(AM,mode) + if(acting_object.pulling) + set_pin_data(IC_OUTPUT, 1, TRUE) + else + set_pin_data(IC_OUTPUT, 1, FALSE) + push_data() + + if(4) if(acting_object.pulling) - set_pin_data(IC_OUTPUT, 1, TRUE) - else - set_pin_data(IC_OUTPUT, 1, FALSE) - push_data() + var/dir = get_pin_data(IC_INPUT, 3) + var/turf/G =get_step(get_turf(acting_object),dir) + var/atom/movable/pullee = acting_object.pulling + var/turf/Pl = get_turf(pullee) + var/turf/F = get_step_towards(Pl,G) + if(acting_object.Adjacent(F)) + if(!step_towards(pullee, F)) + F = get_step_towards2(Pl,G) + if(acting_object.Adjacent(F)) + step_towards(pullee, F) activate_pin(2) /obj/item/integrated_circuit/manipulation/claw/stop_pulling() - ..() set_pin_data(IC_OUTPUT, 1, FALSE) - activate_pin(2) + activate_pin(3) push_data() + ..() @@ -407,7 +421,7 @@ extended_desc = "The first and second inputs need to be numbers which correspond to coordinates to throw objects at relative to the machine itself. \ The 'fire' activator will cause the mechanism to attempt to throw objects at the coordinates, if possible. Note that the \ projectile need to be inside the machine, or to be on an adjacent tile, and must be medium sized or smaller." - complexity = 15 + complexity = 25 w_class = WEIGHT_CLASS_SMALL size = 2 cooldown_per_use = 10 @@ -457,3 +471,123 @@ A.forceMove(drop_location()) A.throw_at(locate(x_abs, y_abs, T.z), range, 3) + +/obj/item/integrated_circuit/manipulation/matman + name = "material manager" + desc = "It's module, designed to automatic storage and distribution of materials" + extended_desc = "The first input is ref to object of interaction.Second input used for interaction with stacks of materials.\ + It accepts amount of sheets to insert.Inputs 3-13 used to direct mat transer between containers of machines.\ + It accepts amount of material to transfer.Positive values means, that circuit will drain another machine.\ + Negative ones means, that machine needs to be filled.Outputs shows current stored amounts of mats." + icon_state = "grabber" + complexity = 16 + inputs = list( + "target" = IC_PINTYPE_REF, + "sheets to insert" = IC_PINTYPE_NUMBER, + "Metal" = IC_PINTYPE_NUMBER, + "Glass" = IC_PINTYPE_NUMBER, + "Silver" = IC_PINTYPE_NUMBER, + "Gold" = IC_PINTYPE_NUMBER, + "Diamond" = IC_PINTYPE_NUMBER, + "Uranium" = IC_PINTYPE_NUMBER, + "Solid Plasma" = IC_PINTYPE_NUMBER, + "Bluespace Mesh" = IC_PINTYPE_NUMBER, + "Bananium" = IC_PINTYPE_NUMBER, + "Titanium" = IC_PINTYPE_NUMBER, + ) + outputs = list( + "self ref" = IC_PINTYPE_REF, + "Total amount" = IC_PINTYPE_NUMBER, + "Metal" = IC_PINTYPE_NUMBER, + "Glass" = IC_PINTYPE_NUMBER, + "Silver" = IC_PINTYPE_NUMBER, + "Gold" = IC_PINTYPE_NUMBER, + "Diamond" = IC_PINTYPE_NUMBER, + "Uranium" = IC_PINTYPE_NUMBER, + "Solid Plasma" = IC_PINTYPE_NUMBER, + "Bluespace Mesh" = IC_PINTYPE_NUMBER, + "Bananium" = IC_PINTYPE_NUMBER, + "Titanium" = IC_PINTYPE_NUMBER + ) + activators = list( + "insert sheet" = IC_PINTYPE_PULSE_IN, + "transfer mats" = IC_PINTYPE_PULSE_IN, + "on success" = IC_PINTYPE_PULSE_OUT, + "on failure" = IC_PINTYPE_PULSE_OUT, + "push ref" = IC_PINTYPE_PULSE_IN, + "on push ref" = IC_PINTYPE_PULSE_IN + ) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + ext_cooldown = 1 + cooldown_per_use = 10 + var/list/mtypes = list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE) + +/obj/item/integrated_circuit/manipulation/matman/Initialize() + var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, + FALSE, list(/obj/item/stack, /obj/item/stack/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) + materials.max_amount =100000 + materials.precise_insertion = TRUE + .=..() + +/obj/item/integrated_circuit/manipulation/matman/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) + GET_COMPONENT(materials, /datum/component/material_container) + set_pin_data(IC_OUTPUT, 2, materials.total_amount) + for(var/I in 1 to mtypes.len) + var/datum/material/M = materials.materials[mtypes[I]] + if(M) + set_pin_data(IC_OUTPUT, I+2, M.amount) + push_data() + +/obj/item/integrated_circuit/manipulation/matman/proc/is_insertion_ready(mob/user) + return TRUE + +/obj/item/integrated_circuit/manipulation/matman/do_work(ord) + GET_COMPONENT(materials, /datum/component/material_container) + var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable) + if(!check_target(H)) + activate_pin(4) + return + var/turf/T = get_turf(H) + switch(ord) + if(1) + var/obj/item/stack/sheet/S = H + if(!S) + activate_pin(4) + return + if(materials.insert_stack(S, CLAMP(get_pin_data(IC_INPUT, 2),0,100), multiplier = 1) ) + AfterMaterialInsert() + activate_pin(3) + else + activate_pin(4) + if(2) + GET_COMPONENT_FROM(mt, /datum/component/material_container, H) + var/suc + for(var/I in 1 to mtypes.len) + var/datum/material/M = materials.materials[mtypes[I]] + if(M) + var/U = CLAMP(get_pin_data(IC_INPUT, I+2),-100000,100000) + if(!U) + continue + if(!mt) //Invalid input + if(U>0) + if(materials.retrieve_amount(U, mtypes[I], T)) + suc = TRUE + else + if(mt.transer_amt_to(materials, U, mtypes[I])) + suc = TRUE + if(suc) + AfterMaterialInsert() + activate_pin(3) + else + activate_pin(4) + if(4) + AfterMaterialInsert() + set_pin_data(IC_OUTPUT, 1, WEAKREF(src)) + activate_pin(5) + +/obj/item/integrated_circuit/manipulation/matman/Destroy() + GET_COMPONENT(materials, /datum/component/material_container) + materials.retrieve_all() + .=..() \ No newline at end of file diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 4a845ec25d..c1b173d8c2 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -11,7 +11,6 @@ activators = list("load data" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH power_draw_per_use = 10 - cooldown_per_use = 10 var/eol = "<br>" var/stuff_to_display = null @@ -53,6 +52,7 @@ desc = "Takes any data type as an input and displays it to the user upon examining, and to all nearby beings when pulsed." icon_state = "screen_large" power_draw_per_use = 40 + cooldown_per_use = 10 /obj/item/integrated_circuit/output/screen/large/do_work() ..() @@ -222,7 +222,7 @@ desc = "Takes any string as an input and will make the device say the string when pulsed." extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech." icon_state = "speaker" - ext_cooldown = 2 + cooldown_per_use = 10 complexity = 12 inputs = list("text" = IC_PINTYPE_STRING) outputs = list() diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index dc47290545..6a5a8547c7 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -7,26 +7,113 @@ extended_desc = "This circuit uses a miniturized integrated camera to determine where the target is. If the machine \ cannot see the target, it will not be able to calculate the correct direction." icon_state = "numberpad" - complexity = 25 - inputs = list("target" = IC_PINTYPE_REF) + complexity = 5 + inputs = list("target" = IC_PINTYPE_REF,"ignore obstacles" = IC_PINTYPE_BOOLEAN) outputs = list("dir" = IC_PINTYPE_DIR) - activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT) + activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH power_draw_per_use = 40 /obj/item/integrated_circuit/smart/basic_pathfinder/do_work() var/datum/integrated_io/I = inputs[1] set_pin_data(IC_OUTPUT, 1, null) - if(!isweakref(I.data)) return + activate_pin(3) var/atom/A = I.data.resolve() if(!A) + activate_pin(3) return if(!(A in view(get_turf(src)))) push_data() + activate_pin(3) return // Can't see the target. - set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) + if(get_pin_data(IC_INPUT, 2)) + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A))) + else + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) push_data() activate_pin(2) + +/obj/item/integrated_circuit/smart/coord_basic_pathfinder + name = "coordinte pathfinder" + desc = "This complex circuit is able to determine what direction a given target is." + extended_desc = "This circuit uses absolute coordintes to determine where the target is. If the machine \ + cannot see the target, it will not be able to calculate the correct direction.This circuit is working only in assembly." + icon_state = "numberpad" + complexity = 5 + inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER,"ignore obstacles" = IC_PINTYPE_BOOLEAN) + outputs = list( "dir" = IC_PINTYPE_DIR, + "distance" = IC_PINTYPE_NUMBER + ) + activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 40 + +/obj/item/integrated_circuit/smart/coord_basic_pathfinder/do_work() + if(!assembly) + activate_pin(3) + return + var/turf/T = get_turf(assembly) + var/target_x = CLAMP(get_pin_data(IC_INPUT, 1), 0, world.maxx) + var/target_y = CLAMP(get_pin_data(IC_INPUT, 2), 0, world.maxy) + var/turf/A = locate(target_x, target_y, T.z) + set_pin_data(IC_OUTPUT, 1, null) + if(!A||A==T) + activate_pin(3) + return + if(get_pin_data(IC_INPUT, 2)) + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A))) + else + set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A))) + set_pin_data(IC_OUTPUT, 2, sqrt((A.x-T.x)*(A.x-T.x)+ (A.y-T.y)*(A.y-T.y))) + push_data() + activate_pin(2) + +/obj/item/integrated_circuit/smart/advanced_pathfinder + name = "advanced pathfinder" + desc = "This complex circuit using complex processor for path planning." + extended_desc = "This circuit uses global coordinates for target. It will count as obstacle turf with given ref.Passkey\ + is the same as used in door remotes." + icon_state = "numberpad" + complexity = 40 + cooldown_per_use = 50 + inputs = list("X target" = IC_PINTYPE_NUMBER,"Y target" = IC_PINTYPE_NUMBER,"obstacle" = IC_PINTYPE_REF,"access" = IC_PINTYPE_STRING) + outputs = list("X" = IC_PINTYPE_LIST,"Y" = IC_PINTYPE_LIST) + activators = list("calculate path" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT) + spawn_flags = IC_SPAWN_RESEARCH + power_draw_per_use = 80 + var/obj/item/card/id/idc + +/obj/item/integrated_circuit/smart/advanced_pathfinder/Initialize() + .=..() + idc = new(src) + +/obj/item/integrated_circuit/smart/advanced_pathfinder/do_work() + if(!assembly) + activate_pin(3) + return + var/Ps = get_pin_data(IC_INPUT, 4) + if(!Ps) + return + var/list/Pl = json_decode(XorEncrypt(hextostr(Ps, TRUE), SScircuit.cipherkey)) + if(Pl&&islist(Pl)) + idc.access = Pl + var/list/P = cir_get_path_to(assembly, locate(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2),assembly.z), /turf/proc/Distance_cardinal, 0, 200, id=idc, exclude=get_turf(get_pin_data_as_type(IC_INPUT,3, /atom)), simulated_only = 0) + + if(!P) + activate_pin(3) + return + else + var/list/Xn = new/list(P.len) + var/list/Yn = new/list(P.len) + var/turf/T + for(var/i =1 to P.len) + T=P[i] + Xn[i] = T.x + Yn[i] = T.y + set_pin_data(IC_OUTPUT, 1, Xn) + set_pin_data(IC_OUTPUT, 2, Yn) + push_data() + activate_pin(2) \ No newline at end of file diff --git a/icons/obj/assemblies/electronic_components.dmi b/icons/obj/assemblies/electronic_components.dmi index a9dac06d6b8bcc864bce0ca0194ba949b0856b4d..51e3a589d1d63c35e54a9c99952f8cd31b1e8775 100644 GIT binary patch literal 22822 zcmbrmc|6qb+de#FGS*PCh0vz#TiIezX%i`HVnj$}XRI@XED^G07fIR1lI&&>%DyjI z#**wa_F=}%Ja2uz-}`spulxQzulspDf5^<`eJ$^6Ij{3Pj^ixif$pv2%%_<_AkgtU zw{JWIfxt7s50()Ml=ynr<$^$v7GDDsj~h1b)^7GL9`?>oAdq)@;`?s5ITeo3(T!6j zDa9Y?&VO+n)3I4G;+98ezqlu8rkSKr%pF^Wc@z6YYhyi=?vX}7z~no#TQFRj5RB$S znz}~yO(n!d>XnUOt?EoWSep@K@BTJkv{(TSfNe~~G-Jmc)10HM*|7UB)!j4iR=hOY z9+z(lcgDdqTzV?>^pD+Je~&E~D}(MSd$Wj59yCaw=7>?g86_dQ>UT5g=Wy(^Vi*_W z@w|^U&Ixss7rELv{O+5*6nm~o|KdX8tArOGZlRtRLJKaps-4`COKwQ#yOFG2L+7Hi zQ}Ep>aWeRw*;MB)HD8P4%lomVAAxziXEe_6tBJ_GW244iiAYFEUtP`3v0{9cbDs0( z^*|j1OX)h0BSTFCb}1^|)HsDp`^Ogo)iDv9Sm$2vXUBQ`^eID+~AHE2^!y&h35Yb0M#;k*>AAiST@pT>`t{#T|dbE0yl{)o6R)*3z2i`<1sJ z9lme*Zk^6O<`?$Ugf~v3tX8??N~~4$=Uc6g`Z1ATn!l906?{z>lg__a^n1o;6nV#@ zI7UH;&i+{fT|QJzmuT@>;gSAXxn#-lGA z!)}A&-MHk;M$&Dct+;yc(g+#jc=FWhLWa%;MR>w)gMuBbILO!5jETEnVr|sYt6pkF zN8F^B6gTQ7)P}~tXh$@q^>jA)^I0!@TA^t!!#U~`Lt&}5o`!8-)1D8}B&XK`bE`O_ zT7?OrcbPR*6!IbOp1v~C?oAav;MN@chHPu(3gdf}e=|%)OUJ?jpS3^K@La$55`U{- zn`PF#suI`w<_*(Z;LH0JUPyCEmi zCz;GYo5-2?T=E|W+cZBE`_M0FHK*TjS^Ro=YWHouK2K(+kR|uy*<}p^!sYq`_cV9L zJyKIVG#*4Ro_9LB;YbVCqvIW_+P{`9{4t*42%(;o`#;D#u@IUcJl5uiU(phW>k5~ za926YUDuE=$tH+Hi&5l-&l^15(T8S=GM-CWj34FT&Va0}UXoW+01DSx*<1!#l zp!BpQ=ps<6z#$H@ljDms&|J#Lj33^RuBD+!%Q0j@?Q~Ap9i23*oEEt`?pH`sTEE^- z4w;spMXjdxu`0#?49~QGwBwc97>8`SM(f@6O3ktRb;{L@ahDYT3fVw?v9wpE#ZsR_ z`KQ5qA6dt`xV^CEnLHOEN#IgwyhF;+Z)wZo4;Y)nbJXJ?L#puO5A@Tl$SE3(veUVB zt0S=W&n38_mg6_Yo{w@fk12OFF&3!YL1xJf+da;KwJt_K*$iEN&fD`{9|E~GKy9%Z z;QYZ&W@9w$^3v$4^QmStEEWC5A*iZR2vj~b-Vr)QC3G)t-ziwmho{06j$XUWL71Uz zoUMQ>)Rjv(tM^>hB?fFyV2r?()?Y6#e;iz{Rs8PzPrn>06dV2=JBWe)Yp*@x?k*VQ zg`bRQY;2rsXz9sN&8wjtI-$u|Qk<$<4vyEOI~g^c!m1j}SI_(*`c3QXvai3=%^z&L z5oS}3Xw;W^9T>sZ8P4gSyFUf1WnC%8Fk>DeQZSkcq|P0lIxJZ~-7LFf>IV{S?4?}r zVSrE-AKx&~?&i}V*E#E7rMO?<80and6cZ|iS#vvYPWvPXF**@gaFCJ4hEZkdn`IE5 zf;)m(8R`-hH0TcTeu+q;vlJQjT){)}YV!m0t5cXzCk)%9r*01Qr!6+rs5X*ytg2Ps z9(MyJcRcU~a`96Ofj>}Tzw`DOTyvH@g)hfxgkm%--W;JA8@>b3|3rv~~&TX866BTL!3dK9{F=zZIDFaltf_1LR-F+k=J- zQ8$q|P<9hsyP29zV4vhL*r(KI5-oZQ;#XDnu$+7Vvo%x!}MNFxm zf0UpqpK=UiFg#qV@RKx@c|~^NaktJ)dP#@a3~JjJk7&?tvL4;wI>Vu8>*p=MVDww3 z=Umr?k-7wHLu-^KHG8q(Pz)8OEl4voWaHaKJ8*lrezL{}{V2E7G~O1ar}$D@q1e*P zlV=Poih~aWQ!{j9;q5&*_CyQAXerXN@$#Z8c1N)YbHaXDP&1e8@X{mig!|%k7=`(; z(gv#@X0@H8fcwW6s z>el<8&u*lzQrhySDCM%ZbmG=~j3fxFtK#a@HSTt;s|WsPYHliMy5UZN0%jgKN!kh(kuE=tuC#;ho*x4`?*IDgrMtoo;hOYT4u0 z`=!#T{>zD%{KP1ovzY~PM` z`hL3qK}CEdC3F=J&c<9hETb#!k&+<|&#~1zO$NRH(IN<adAH%6g!s_%=mK@od(Kh5LWPY1+<+paV?OGop1J*>nCFuG9uEoZh>b zm~fBC5qKA+l5zE7Y}@x!peVy4_uNNGL2SYqN%Q7uQUp5U9G?$4I?E>)3vB#p-Dw?B${!{2LT_K3$zh%HT{rtL-MBWWvvGxT&)%zmW ztYe$_&JaxRPrv|mGnvl!aZPAwK&rX;aVjg*jL0br#t{Z_;R0TJR>w{D^={HlQC;jV z%QqxvnL&0r*ILH0D=Id8Z*j}qNy%)GIkjnUnTR^^F>ADv=Op z4n-*UnTx$)Mo$pdDGwhz?-PIgl)81Zfs;f#$6$#WFGYsBFuzmKr`(}2aSA56{wY=C zS6bb@Jk2RRzU567`VlXV@>tkuvNwJoe0XS)g?s<(p}5u+3{O5)Oz{|Oj@0=WMgMB$OafSx!mscU zwBu)P1JPJ;#YV@1lV66#@5$lTay#+IZ|ATgb=y~wYsRn7)83T2CA^Gh8fi$yDURP6 z`%iPI0$q#p%TRWVoJSZF$Otrt7r0=#g=vd?Fu5T2dOhX29OWtI=0ob^+vQaJW(-PN zf`!x@+!kU(g%+^6yX88ZOt`Mv`^w8XZ0X@PZPjJuF`GFi7>~mwt_T9_(^s8a;QHf* zx+yZB>uYN}{|LV@Cqc<&V2XfGl%6ne=wDFh3yZ{QwwGb1?>xZkO!h=B=)7{9am8LR z=-wY*-?@%Z_Bb%BoQ{K(mT+e~VdPmpvzrC{_379l%n@KKqxK_22F9|HeHVx`DQjw5X6R;rNs*QM-zs z(0dmQnEsRDWG$A!hHarr3G1P9)`cLw>!u!~@T#mIp`#F|lPfjn&&Ez(08dQeN}_bf zRZ04VTL_O=fjEcahul-UqwAt>PeD#+0hj2n( zhd70-Hm!&SOA%&fgv-Y}boxxs?9>*xec2%Uc#LAqdHMOp@z>hQO|v)rCDLv-mfrUc z)|iayT4(i-`CY!BsA)(E?)cE6cXH+-D2XCt1e(4Q+j4ARlVvEx=D|YuGdZhK4YnMi zv90QcuAe&v^r!pT1(aVzR!%(pTvax+7;{&AKR2h2td|GN>NS?An~N0h$P_hagV}ME zcbqhWj_;zmrl>~3cUz>HJCmi^52dZ>XXv*BBfco%IE2iBF75*^+OYv8_pwvs_=kPb z15+JPKm7lLRiz;e@>SrJ=Nl*EX5@;r#v? z1d}>1Nf52g)ts+Xp1+cSS6`c~;S8)b&7V#w#mg!E$PAhowNuUTOPP*z3pvKirFp6A zLkC=M+#pA6e`U*W6h-jL9{7?gfn0Ja_*7M;=+banP%u%hzi?V-D9vZ(;%B>pSvyU@ zNA8z@$=uJby6Q1Iy=36a&&So2|CnPa;w}b{w=hSFj(HP2l{^z#+4;!AR*&>9rry{~ zJ+C=oUj!<$veEm;=jCky)rwKdAJ;#%(E7#qA5~(!egsZQD7p6wc_e?}3Lm0h&y0A% z3cjTC`U@j6K5(qa>5u*Ms=(=*yl1i~>(nh#gL4l-UcEOw?Si?){fxKd^@3kv<`Gr?ogIUQ zyezArmCN_uD<-_3esPRG*=vO~yiV*aH^A@XsC!iqkhZq=Mz=HaQ4PktJ&-@(?EAY{ zal4q*vk)&K!5QTArJ*ZK_ZA#s&Kty9o5TxUtJg+kS7q0DEfayO;Yq3B_pN_ZH@0lSO4O&l>*a z`sQfwi(rj2vwj@CG`w*VIB1;Hfv0yXrfs6Vz;99k$4I<$$!)bURktstH0Kzfsa?(sQH)S+ zMaHOw-|@hy3%?k{CO=CAm*6tn_gAiuez>vwY#NC>0Y$$an%U1_5_|DUbXCV7dM4&o zl>F1>=@V7CsDrHq?ThjKzM9~v#d<^^g;vK`yY772mo7<2zZ_>Vc&Y*P?OBB(b2EqJf{D%I42*=e{PTug#rWL) zu&h|Gd_FncwCL+OALXB3kd=}2Q&9w}59k;i$4*=4`rdyuv)o*B)xpxE zpiC;{$e~|4uK*&`cjp7#{V>+ymYGH)V5FF$jL%xAhm8^D>(D|lpPxqU#lc_)2VkB&Jt@DI+Lq(wCgR;$efT7dAZP$__|_nq7H#Jsd2NJ z+x-MIO4Ye|ZeaQAxAhcc1M*~6xx1!n6JoT){NXc)(GvQ;dd)F`&7EU9bV~*PS(TrL z){*nkijmT&gU*PdWF*Ox)bJNYxQ^rC1OlvDeo*lY`bVG*J$$h)LwM~I!usH?jfcZ_ z41ZnSVS2kz z$0ju!GeOR_ELp^#O7;Hp{5X!$C+^XI?Xr{?ttNR;4<&!l*)f~&^rS|z!$kTHE$Yhq zC&8(}izxmxlBHKkDPV|~qDQ6Fb5RqOpaB6{`lN$;SAV`z$NDW@JZLdoqD$Of)oiA~&gCo4MO%4cr;%;P2G~r^wV;>N?mp1|_W4vBBEfIa56^`}QIy*em6+Mk_ zCW_a4G_(+b^MTIRO;76^GlVHSt2@bwEstL3)Nur!A%~&97qFuk5o=X-i_e|~Mz7$i zL}DgjCKIwg=kibFmU8`smwL%ae{(2{>q4S2cNSr~fxmaoG>@uxxMrtR z=~HnPgC{9QqT2d6&iE{17w>)aw$4IEWI65>egAx9*84u%ANo>rh{J z22RaaHu9Ci+gQdl$CtrhL!EN&FWfZ&mN{ z1){F5ks6ia%O+15lQ>jVRly)}+!lAbo0{IM$A@232@-xKEhuJ<#b9eYeH2hDq9h0BMdY)_34ghi}of2JDW_c9HTG# zMa#_Vd}EERLtOhf2|KLBh`$9xHdhGUpw1ChyZVYkw}6Dipl>;tvmms2oe?QQ>G1RE zQvuei)eZ;VOKZKi--e&6gVT9|Kr&aZgfa;Eb3CFQz;d^n7-X+pp-+zsY0#z(odU)` zF@U0(+C5##^!xRVT7Ebzx2#IozxEolhX6fzALzan%l2n!ys5qDrs{p zz3r_$nK4JZb4vA0^w~|PF>>B=*%%+AaL^O*+<>k}hPGl_ShlE& zYbs(mgC&d>x2(hnQn#pahHq|W;t2Y4IAS9Dln}al_H`}gF9b~Y zMTx~M5yblAr-pIw&d zv$i_^xNUEJq80dY9cd2TUzlxCDzp|sDhKc)GAlW%Xj?K)4ZBA6iy2;k4WxETw~wnM z7X!L~qgRzIMOnO@cKsQEEAP*I1`pg32Y-r#9rV0OtU+zQfzSM(B3*JLALU96nA{{~ z4`5~i=@NZ0X3htp7Bch7=kab?gg~JC z2vIEQiz8)e4`}=HEn|?vEgb-|YUUMFd+T4*13ha5EvnniozMe1?id?;58z!!X|Rcm zn2U%_9?M}BhEg1v!=c6OzjF{wR92j_iHlx&TKz98K}@HKb?E=Wi=iZU z?=rtX23#qCV;^bDmsxZf1oxv{nftYhzU&Z?pq3Qngh_s3K9hC$TeS6-`ql~mt@tb* z51YOQw|?N7L-7g)P-g<#M+2Ze_l-E55^x&3GU;$=QR{jYj!-TQRp@`px9stF{ASQx z5lbB1M&&5{oYAB|U%DBeIW_Cf$tkL^hiB008S)i`V)3 zNXRfbJDb&{X2KbRz6^O=A=MR5YIBBJ&I-=4l7IS?@Lc?Go^fSQ^}Xq%Qvm?f$Sm1( z$8xrUMSPk@MA3*5$xi`H)vCbX6qvdSyWX~+@uDJiyNips#(+8{pRMz@y_u4f+Vp4> zRN~hPj3e27{uedVdoH3pS^eOrUSyaMQmNlli--b^S);9gSRJ@|_5dD`*YV$_fRhBR zv_?BAUIcsiO+WY%*bn|VxYEI8XC5vPh!g3-qSCxiz?PKJhx9j_2*7aDk?U{v*GG5v z3(GdfL%nh2=|yrXBJ6>5Ync;bhM|>8G8P7`5QaQO za2dBrp8X!d`Qw?KmNrM!LmGul6i35ACJw*tj;-U_uea_kW}n+o-lxZwmC2U*AGlq> z{DV?T9TT_`kM^H3S2v#tW!?Yle-AC{5y16&nf&u(fGRL&Y-g^8x1aH2Wne$^9hgr};_Cyu-pptg z>3WVBwLM-Cx#lkB5$@;-9t-aeL!@L`(^?yVUI`$3RmQ`9O`$n5Do|5P>Bknlm7q_~ z;#D}5LGY?S(i@ATjqE67aem^LOOWC9n2rzE!}kcv-*|Z3 zJP%a;Vp!~n_iShc6nhCNI#c|(Qfw2dF+>u&=FL%PR7@A^2+6j}B|7b!YpfVB1M|ve zfueY(yZ0zZ;8`6uF_d-Zb^?;9`jWccqbj{gQe>`$WKHCYgXjbx&}LfjV@h0IHcIhI zv@r@PPzQAzD`N({nuT$^Ncun9a^ zfdNyiemKi6{sjiYk$O|)8QNon+S8TYPrd{V&7s!H+Dn0VuHT<~(?L0!`px-v*ET*o zOX}f4#KDw-BZ_`Xp)pjF&e>s6`z=BnqC5@9v$_KW+BhQl zKNQU54-&q5fB&;WPy^hIqfy&s`do}-RbrkNZ0wSZ4!#MTXhq~2KO~iHKf5s_mDQVv4 zOoSk;oX51oQxgy?1Cx=U4cB(783aynIpKh z(FM;S?aeIzg=eNbOL{2Mqde+3x^S89xOhvk!|yY`!##gzX5UkFM1J*(luBJ7xaZYg z(z&eOaPgAroc+he=6!LHjWp-ds`&lX2M}ELl}`Y4K+uUYs7E zkLWC^ql}?Z=2|qs?~lz!E1N4obmu<%P0SvX01APO9KBv{)&#nofl zM_njDWP~SxQItZQOi2SZ^7Qs%X%fNPzIf!oU(FsMn_dfjFd zTXjY_e<|-5inJp;czPg0P3!D|nb=NNCDWCTKyWrdPy=kn?4+n!Q5%s{>$d9rGpvejaGks*F;1qo z_l|}56?68n?q4szl=}@I-QmC!Iw8Zu!>jv-0#NZcweo-YbcO}vKVp)^LQlhgYXO|U zvA#cYEN(x_S$)6%@pIjg3&hwTfw!KUZ$9GeK3=xpQ`Y!5O2GO*(|58Dd|HnKE=KXq zM+}xzV3$#i?aZK1fVsCwRROKC1+x6H9|rsid#jbk(+|%9*Aeq*tHG_!Q_nSK6`t>H z+p5x^25^Q31y5-G!lp!9TU*H6k|n^9o65f#67LQWRs#O2rtlKv1!p~7+ROAy{-qdG z8=mE_AG8bT09G@PE!cW=$X!&CxZajm_D>vl(>edL%<}f@JC(;lISld+%<>LKhnV&K zEb_4O5>X^%pYxxJ+O{B_f6%@tUDMa(0ppvszpsLtpNC{%@Nz%)RFBJ)jU$}^Ur3Ed zqunc;tcVyLr}%|;gZOhoZk!vb$@a8h?wF#NBX8?4wN z7p5+TGd}j)8SP!jirkFXvd;&MCnZ9V;TpinErAA>KQ@-VJMzVZ&6W15+_=9MflU6a zZ!u|@zgQv6WQI;55JI4tl|r<(Q(SG?k9mX;1Lz3RUHX>1up-#87aF?1M0)Gmvl4m&6nt*zJwm62Ked{S9X&gM&Gb*+8{0pw9z{y|~Z?x-2<{9!~!`1PAmfux`+H|W|0mqnO;udd-Zr+yiy zkv?=3mEDZ406$=*QZ9{55NSj+=?ndg#{>PfXEA+!ca-LxxGKTRg*EP-7|_fd=C5ScWKYdiK8RS=`=p?4lF11C#qZ z_)2*aD>C>$up%pBJ;{bwL6ZiBRgtU;Md0jag23GF7rlVH*A(_+x7ySxJE99Qo);yE zylE>%$#%^zVCnNNo*DL+H{EA{zfB5sL6}H_2=EoK=r~yoXm0k10`v6K~K(A_xUBCYT zT9lh+%JbCI6QL&$xmeuM7R}!}Qf$U)o^Krut~&Q8{BmSIN)W12BhnMl2QFv zACBu!skNq;w0wSZXEvLRaxIn4x^l{zdSmtxm)gdPbh9HQPKuTaSZ4E)b1 z(0?`UUN@X(08m#6G5J1R+hGQ&%XK+i@v|sg9ru|iBEU+%Xt@Ayp zy#feXa>gzIJAao{*e}IrSx2t4)7V+vtYJjJo4~(A;tTV_a`G}j{i&~7(19VOZT5WvS{1ao?NbkgMsLjnm8e6^0g#R8 z2PjEu1H}+`_6j5yj>g>-e-*W9tugRY){)h@ZW@jmc%B775}z*A851euuEe( z=8kzgSd~E#wel$IB>QpokN%%TDZYnUCL5?yWS<;h4u5l``|w}ibN#%mKq>xBEJsp& zi`#=rF!pK>{S<&V&7yuHj%I*y{@dMiAHs$hgcS2Lyi#@5&iF2g%>PMq9=QrJ&7)Br zN>0QG9K5+rNQ?{W2iDH);uIgF`~ykqg5fX5BbsO2$#1V1$NEGA&wC!g z*PWE0cTr|!P7@li9Q=w-r+_1e9$Di7*> zt8_57WDkjA?OH`R0juk0ACk-A;RPGeL!Dejne$kWRlDYn)p{20fx6s2ONQCM4R`#; z4~+fv2pS#(>=z-wy|v3(5t5rvzFW}VUAWgbJe=2!E~M6Ztv3UaQ2rz#&s5RcnGAg+z)wqlN|safWmPQS46FqvvmIsaLp1RGTrQ78P!lFaDyH-1Bfw? zYBV)9DG9|Kr=(Jj4%tpsRn{tuA{)UKNWjpjWAxdW2nzhgHfazyjVz( zYjk}=EvQFnz;4^ybEo8Eep0#u)5d$bl_=|LizGc%JUIp2zF9%9i&7=mPzP~6)MFzk zTdeD$V-WD=sHv(7SkNw}M&9xpcG=kuHi{xmjN|B5QSNrw|MU!oeuU=D=fd(;129BR z|2);Z3)@3{?+i4{rq_Z|JpXAQXtE5GThku6?CcCPn*o~7S_O=o-4MA6xTp=pxavSV zgYYUC?$2&Mrh)Q=mNqT4>K4+F@rgHM0HJ*8-;-;EDw0|{cWeH?Orr_dd;MyFIncsC z6Wc`v%-Ru2_a(;UFLS50awMDh|Erk$Pl}B)Iu{^7yTcW7v{JxwrL|@qD=T?D1R!b= zYymts0N(8A4^-O=M$mdoi-)b*|0?*iA(|L4ng~ui_vwe19T@a)`P~0mcX*i4Z7K5G zL@+xWTib5Cl}o%Wz)JjUfvYOu^Q0_;Jwb604n?EaWpD%pF%*vN9|I; ziWOOsF2Kg^-OWPYG;xqTe@ z>Y@DpZr@MTkKvxm%>WY}rMp}wa0)oRM>|bXysS1mM&Nz{@4t86HR}0ruE0^J!3lbe zqcaXX)qS_a{C>QKYJc}BsPlu zbcBNpnumPWMU`b;k6_3FE~k3Sv3$*rDbz~U|0jB4oCR6Jgb_*;6bmH#JzK;MvN z`SS%~^hQm;Q{kMh2zM9c;-@+P>(@N~R%sHDU6=3xcvH&QV{1OKNzJnS5jn%-Sle$K zq2}t+wdc7y!6w0*DAp+?7VmUBfAB8V1laR1fvJW5by50@`jIU7cIN$ko)VSPr`HeV z=)L|eCMm0Fq>Jp<00f;Yg89Sih}^ouG$gP}gqsK-4|3rLKc^^eO!EwX3Zo5kSK#3C zSJ@zi9)Yc&GC>9XQ@rK!eIB*GBB%Qa+6ZGs;2NmFy@C4xvFdv@zpJ{L*O|2tem@gZf5C!!lG6 z+_=?iy?`dFyVNYqO5Wx7=gYt~GF++k`Tz`?$_tY_Y;E+%RuxW6py7K+p%;Q_*>E(< z(XnVh!1@Q>B{iTb*Q!C`Fks2P>SS&eAp@?A0N}Pi?uZB}u9{9A+ZY5mZSF4d^)Qep zwG?*+fOGgVCYGUG+{NdD#O>6E_j zrvjxOJ*%tm$~biZPC#1sQn-wtJSDj6GrtB|vR;S}QHa7Fkp)scs)TEkNb)*eJ~=^O zmVh$*@g~9+TO#e|JcG|@Nc%27BV}+b0AU(=JTT;Nny}{%x&)WiA6Ml_F2F5r-4b&? z9zLtOL1=fb%sN!vm=3T5l?boxigtf$YKpWuFeva3xT+@xJdSR}A~yTb~Bl z6BuUYPElx$3QHtWh#gGk2t6pTQ_XmKk-@nw#T!~QM(}(+9oQilFzeI6sqab7oy*Kl zTklD-nJqAp9qoCQp;J8~H>_}EOW#NeAnxT$bc%fqw}}E5?m%|!5_GYVX+a~TfID{B zEQpKvq}mw-NQvW15#DVmdbVQflhNmG2p6BrsdpsWL;&SYq~d%+3b=3&(qv(WyF>z8 zf9^9=$lalSmwPZp1x@};iQMgq31|lqyNlzg z^ynb{BGvziKSmlWWHPOy9Q!z^H>(V-1WkYJDm;{>Fus-qELgn?Ms-O=vpRf2bdyGW z`2d uo_`YB}dbYwS(LD{8-@ix6n1k;|sS_jOoU>**peT^k>I3R>i2wmcm(JNvXB zhZ9N-T-qD$Sk9ja##qT)vO?ZV+&^~j-1u|C;nkbhu9(X5n3VNU$DImub^7Hkoy9+Q zjG4{xm0H0#(p{5h#e&I{I~>boy2CpOKr%>}!Hdw0osvtEEL%qcE*t4q$?G3`@9hYw zdKLL{#P8E?73e{VQFmz6An$KJz$gI)@T}08Gu)j?lH%$p%I>HG>G1GiyR)%yM0jZz zg5BR&s_#6s*lyI*=76qM$6l$>Ky1ZRa^{l3qYpnV0iuBHM=4AM4diH zIRuqDj?3YM*UbMA)lD@`xLT*dy?_*#wc3cavwSWo+IwkTp>-)C)&1Q7a7XQxRf+0l zeqS4}h#QivE;yWa>f!M^j%El1@@_UaT|w9b2QmSXR8yDMa@b?nuy0d`BzU53#bUUr zd(JeYq9-*c{fPKhST{-Zqi*6w2$;AhmMfIqc6ZB(-d$9r6Qaz!^?X>>*Nc+lY6e1MJ4{{dAG9!?aia*h@M9!7lqk?edlTCp_M49Tb@N0l>w3jfD$>uaZ;&X_Su6 z&C6QX419n9hT68RC>QFC{r#2#kALyr8oFb#P2bS0a?Ws(2ssIsH=J$^fhs| zW-${2x{N_R*pP(N3Y>Wi>#||g&_cGMa)EeoOuTkt7~p?9E797~BqAhGjeD&zVip-b zi+s7T<+kv&4mq$3Lrj(>T*_Mm|cbEjbUt>yrL z57+=_rg6Sb+_*&HMKmhNyzi)QT%`x~H=neciqGi40aum0h3`(?v<(;7>>}2gWSYm30jF0_c zT!pXA11|cvfnqu)YZ)MNs&%>Qi=Ezx0XhebeS67|1hfXXru)uHC?A@R#VYT{8s zA`n5|&bZ5kdj~iyfUmU+s0vZ1(yNV~58tRk4|8!L^_N^(+s2nX0c2ulwS{B8dX@J~ z!%KXgaYn$}@-2PFj@D6QHqk1YE8=qV^q1TT^{*Fzi(xWK0FdWF1oz@ZYWVW_<_?Uv zb`l$C8++SmV+WLgtIK9uK3YkW*j{VCQ z1cOf1u~=3;c=v~lqanxL?OG7P{F%-5eA=RQjt1V7>R%i+rx_9F?R+VztAzHI4C1Wy zZ6q!J=dR^;bfYL3*o+hRJ6bj{X z2iIHSP%M>b)I+(MBGc(xS?A^LdK7d9Pa!4O0mYJudOm$FJdV~|5)2%v5i~9B-uJ5p zP~mk9iho~_Bpq-X11ec*ALP}xKQwNmwx2F48jQ>Rv|)zdXq85~PDoZw%7LEHdf}86 z<4vHX3||5UP{tM)xtV}a{S@GhBV}i%tLEezoF#V_Z&kb+2rao3y=15INo3K~MQ2+{N;CoC zGH21SDJ=u}W~+`!Ip}&vQ6h>>?scsuI$x5&bd&ise(;iaknn_ zjsTs6Q?=KK1s?!xB#)H4mi%=c#i&`oE4^dIx;yX}N&)UoP9B4&JI5#Ub6DOU+4O4| zJcZrf`GqOX3J{aC+r56A+huSrLInU^|~e0|d|ji1`*5P`?ilga@r}iTEk;Nxsk9)m(>8Ijo1B08Vz) z_;*$l(!7YZIe-=%r9vw;DSEIfMKv!*iC6*=)T`6t_vN9Jqoc<4I3Txl+@T@E*0tUf zXsZrR8CXVtt=Mi+Swx9I_S zCBM}p7!d^Gf*$?90CdiImb~l;Xh{n@DDCP?I#5@JYSmhepJ|`FA(G%{Kq8Y!k&45> z$3u(wW!zW$N3HksaAd#LE!BzqD4Gzci;4432vdtpWQ<{jGq2LdQ2gUbQ0acyo6TPi z=%<_PJPwPz2a zX;;m?rf}*;lF1WVlB8K==VXlGLC`~vlCcA^4ZjL~z=z;4 z?m8O&b$Jv$(k`5NBSrLK7_3MD1_=K;@bmttV(O8HNz{e!c*8b=q=Dbnj+o@_UYO8d z4N_JGDhd#|ffut-jXLJSVQhk10h5mV&>0}xB{#_?>T&d776ES|@$kJpz~+`MLxQpU zN;2wi?+fvM|HRIkbf3lfDyr8cb?I#`-uEO*gfv{+O#m|cH{umKo~dw$ zJYrUc^Lw<+p!KSh4v2|sgIyb_rEX8$eqOL4x;A2rXk97tuJ_t2gm|H6FnROi>|N=~ zk5Vx?oBGcKuc0<&dHHKM{BityubLeSPJ=>}L1LOF z<+$E74<4UNQs<{%G=g>;jUXIyi5}j1=)D}XS)zywHOoZpL3pGrUX>xD@3?d6bt@x?Kypc+;R%=V| zme%+h*w4~llE!}Nzue5NLM3{v(r-L>P?FdW*sI9mLf`@r=Ec{ikPLQq^J^wks=1}3 z?{ZRcfQBUa1@*=Jwj6~`u06En|LNnpqnhfzY(gkPsQO6}5fJ@QDFKldny4UB?FgC> zNSVJF*NpY#^~7NmyHw)9vmVJ7Ky zS2JoCP3F}IH+@gD<5fPE(l1)DYR3y+q=5QozByh+aTcyq+a)vMVVwLSOMze`i-_Mv zgv^Af35U8HM#UVGf)N%9r%jb(?Y%V zC3Lbm;h{JBBBf!iZV@>L{4@C7$c+syj$RAJ)m~bz(($rvt7;Wz4xl{6HP&;+ z3hud!5SRpXvVN5I;p9D5*n=lJ@Itt)yzinOKmcqm=!aNPHR~G@tHj+BGT-*)02%0v zb%sAWxI82*I)pi;g&43p_&h?f*Nm;eqV3X#SJbjpk;ZD?@V zAlBi6$fL;j+;L{!nr9Gokpy>;k>9Fp*0@xV=MKTl57#d*oiZ2__2^feHEf^T%RkTK z?#oKrKl7boWs%DznBPqB&lkROvG`yw#P0d%us%c`f&aTB1D^rKXp1|ipkY)VH1@&o ze9_7WDI1QfDl7vQXAN+qHP3ezeyBDlp&ad8pea$o6E+3O`snbM00R;whT&=d>c6DV zNu*)L@(6_o5=zQ>P5QH7khos@CfaqpX!(}`J7 z#1j$A{Q}@zE6zb8U4D`DSjZ%J^*;G88JV;+W-f^y`g&10`C1sUqS8$EOJEMMB#$Qy z!|8Une(j86=;G1k_D6Gr6x_M@V(wKlCuYI?sxu3+Ma9b7_F2$m6l*YI5X|xqy$?@S z^DD@CC^}$lv7;vVFAmyYFJ}CN=L;@CU{%-$=8@LxBc#TjcO)%49w)YMh2%=aM!G}D z)m?kk1L=`$1zi@4<>(Xb9|4mI6GR(EMT+D-AkLBqP(h(GO7{g^~; z0OL26+A?N`|Ag+lQn9GkKOeR-mKe?jnGD})Bv%ww$bErED-Wq|`XTBco}e|NzBms2 z)lV=QO8=r6G>x#o!!3 z7}oN0QwAuNoi>xE0T~;P4ZRgiZfc-u-U8hEdrY-UG^&kvf(IGo&b_COU;z*ApmMbG z)w}YolC_Kl<7(@7LVc37rdPk&q=T%KiSvpLh~F$Y%Xgpd zV-pVK56kuF4DvUosapGTWxNh^`KF{5)LvT_S*rSSpviaP^*B2zK|BbMX5#5r@?!S+ zsQYck7YofxMmf6|xpGt%72o4B`1;l|6bDHOxrGtUbCrj+dcn#__z>w|L3wUCP}6NA ziT)rUx1q8Nx7Ob<*_wNTOB)ym#@WYToE(46kn~Ndz{&0@Wg5~>p4%W!P1@AVH^=bl zB5Gm_Ttwd$MCSr#_H8coE5_)!^o*{t{qRWT`l}iFW2#fau$U=i!LM`<7FX3&DnTXo z@S#w7nvF#s=K;ZzmGQgTe-cI z?5~S{VT58|IxSy#%KS(@FLJodHo0aj0=r+!h6`8i{f~al?^mINr9l|gyQAkHvAlx| zZZ$f*=lts6F6o|(v=T=@xnXIW&e^khDRB*GAcW-H8;iDRa?H2&>(8T*1?!fd@vT53 z&+!hDrRXFJ<6Oia+zh$510N>WmUQ;Bc_xMWr&q4kSWB6Iqs)8x9qQz7yAwn(9WfJPKY+kDRYc3Q|uS z^!F)b1{InGTvnDoQFN3%KaBe;;w0K?UpZ}s=tt7OaZS?!(^%`kM48N3xYIX7hPKLk zQ<^qEB~{>y4lBKx0D1>n^*xc*NWxmT&Bd#o{&6ZEJ5`8@Y8#6IiWdC)fw#OWt`rBh zdd;(K`ub`v_qE^YNp+oDihsBuz*BLl{yEV3&1V={`tWJ!S63SkCjXn>lf&F=Rv?gX zI@Z26GWa4sG2TWnZGSMalI*Kwb`_VEpeJ<{j;`!Dm8IClC$4rcSKeq~2zOO)Ofu@) z4tA|Pv(c*`;l5+M-9ibYo*rI{s%+KRNYv6^cbyEtu5hGao14@g!bZn3@lEr#Mp#mo z5H?>cFYxBJcVS1iB%sxxv)l$nIWHRdWp~D^431i5ef=)oJ9t zp@!ZTJ+@Hd8-e@LywD*Lbq(7XcDE_F zn@1ayxOAYk#5k41+5!vjHDGE$u3%8x{vFb<_ajur6&;$ubY~8SOT*UTv z^!1f~u^GK{FwD?9Wf8zHHx*!4qTL<+^KZ&uKiy`d#&2Kqg`=U0@K4N`uC9lMgP8N4 zry-xz_xN+Z-x#4nRTLX|$joIZb;@ji_(!v>jGlg=fMDSDYG?0kxh+oyY;EKArxzCF z$%oNYY`0C>*znPCk%@hJyJF^dMtLDa4MFMzg9_;Dr_64-Qg+BE(E}|ql;Brtdb!n% zsvWtL*9JYC+qo^5P3u=Qir{s^-G5`ZvCaJvD_a$yQ8{`vU$7L~VVxs_k~I@5h2oDJ z=9nCVD?XqPj26G=7Y)m`qcsp>9%cF<6(D2J?_c()$kp_A6t?MgIC&X{uHQaSZVti1 zdC1F$U<^@w=<0f2>-J!Myx7W-_}xgKF0o3Nm)3MFUnlK+C(d(XP7edDFa(Mpv!3V< zY~{!a3w9v6(F3{;5Y2-hOVu*IGuax!TOOo>yL5;#BWSsA0pNjg3>Q*cdqyukH8HX- z*Y%m*`+-boy_f)h_cHI0ziF+ZVUFC}WqQw}$@y@lQNp_UZHck0?p_L&Zz1bOb;(57 z1EetJJThBYoX06lR6-#k^5x~@S^lGe?bI%wh^1x!m4{Fq*c&ucs1Dj)|y;yaaS?cAtLcXLa)nyYAVH z+m*Rca(PD?gYxFhaqX?K$R|&qo^f)L&Ck!rtGFOACR@Eollx3YWlzgD9co)a7)SJE zFiA-MUK~pG*iOfQ=isl^0@;GNeF4O}+-$KqcOGKWY=ob`xHvu=dR`(1(PJvfH2@Vt zP$lBMBc8}I)K?mro>sF#Ia}mi&p(_4=|vZv^}$#cZuiM4ZIKFp_q&M(eY{?CTjm=x zVNSi9PfMd>#??iBiZ8x2NFC24akbKsRVW3c1px1 zKQs;7qH+vuj}hl#0$*F?#K_yxKhb^N&QIbHS`aEL=B^(_7H zIre0F@errdgVk={A;j!m0dDw5ysHG4BH?hAWB{32maeH~J5wGx8~c{`EsEX`(8ac( zp!_A`B=lG&Jc%8!JE_ulu$K3eHE4M)lA?Hftc2@4;|QH^!e3^x!0>b2r+w~G1O+#g z*CDF%@TJHyb(oh2B|ze;L+;WP;vqc-i0iUo`y>Xin^n$c<5?!U^P1Cz&vvO)nK|VA zFY)VpBhN)Wde^MUdvwpWSZGzD9?x%Qh%(+8-H#M^ka>&pjP+Q@`nQ7MlnYS1*4jbT zA+gyK`^$e$_2*!?J`{vi2T0idu~hs&F~#s3=`wB{reD9I*ulMb_WY5Oz#gCc%}}AI z1zGTzvmAqN1DA+@HE;a&yfhgA;1`tpnTD=kA5U&U2Kku~oPj80&*KX(fM)?P2Whn5 zTna;n)_#i+0wWijzJM&U+du#rppj12lUE=*oO~ub%d)31(p0r**~v+_L4S&n@Z)2* z5hZ|eq*K57i2eiqDbVU?(9Ln+=GfdQd=yAU&O8SyJ*~;+MX6>J5=3 z7B~8Plo51DhnuJa-%+Dx0zu?aOC{DbNPQEyH%$fhJ(F8yi>0{j`_J#$+^{kgOuNUX zDu~hXWj=&PN=$J)t$v2{)9@e|?`i5&S=$EY9VqUL(tls-joQc~52>%_^(Ce^T<~03 zQZ)-Vfm2zrBwwOtlp%wHnl?r&jVT}foF3mjni>G5uW+Isa+|8eWfV|$ zrXMqJ?4DWU7AejGg*hNP_l?ZutZx445%G4gCJ=tZspamX{Mcy``~|7%E`ngHA+nDR z`3I*pHH9|3=56`o`lfImK(J9qj8RT4-&yULDOYlHxCN81f@GCD(u2>IlFtNI9zQbN zk=Z|otHG_O_WNdYySCT$LKbu*O(aLA`&+rd+VkQy-CGa!r z$%(;xwy(JSjsCry=YVnM)9oMF*BIrDqP`<3O1@f#ffdeJlN-n5=F zBN<46-gL~jRA{|by}~s=R*;Y8+j{Vs62Co9d<3;vg6A_vOaC8)-pmx}mI+^dUuHT4 Q{Es0Q49w4!oWVr=2MVvW2><{9 literal 22954 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