From 68ec6e6be5c15666e4e0ddfcecc7c72995e550f1 Mon Sep 17 00:00:00 2001 From: py01 <60152240+collinlunn@users.noreply.github.com> Date: Sun, 30 Aug 2020 18:13:15 -0600 Subject: [PATCH] Pipe Sprites & Visualizer (#1954) * Pipe sprites * pipe copyright * SharedPipeComponent * Pipe Visualizer draft * missing longitudinal pipe sprites * expanded rsi states * pipe prototype fixes * Fixed pipe visualizer * ConduitLayer enum * PipeVisualizer update * halfpipe sprites * yaml unneeded proto removal * PipeVisualizer uses its own RSI * Removes unused field from PipeVisualizer Co-authored-by: py01 --- .../Components/Atmos/PipeVisualizer.cs | 69 ++++++ .../Atmos/Piping/Pumps/BasePumpComponent.cs | 1 + .../NodeContainer/Nodes/PipeNode.cs | 58 +++--- .../Components/Atmos/SharedPipeComponent.cs | 74 +++++++ .../Entities/Constructible/Ground/pipes.yml | 13 +- .../Constructible/Atmos/pipe.rsi/meta.json | 196 ++++++++++++++++++ .../Atmos/pipe.rsi/pipeEast2.png | Bin 0 -> 217 bytes .../Atmos/pipe.rsi/pipeFourway1.png | Bin 0 -> 556 bytes .../Atmos/pipe.rsi/pipeFourway2.png | Bin 0 -> 538 bytes .../Atmos/pipe.rsi/pipeFourway3.png | Bin 0 -> 545 bytes .../Atmos/pipe.rsi/pipeLateral1.png | Bin 0 -> 273 bytes .../Atmos/pipe.rsi/pipeLateral2.png | Bin 0 -> 278 bytes .../Atmos/pipe.rsi/pipeLateral3.png | Bin 0 -> 278 bytes .../Atmos/pipe.rsi/pipeLongitudinal1.png | Bin 0 -> 329 bytes .../Atmos/pipe.rsi/pipeLongitudinal2.png | Bin 0 -> 326 bytes .../Atmos/pipe.rsi/pipeLongitudinal3.png | Bin 0 -> 321 bytes .../Atmos/pipe.rsi/pipeNEBend1.png | Bin 0 -> 265 bytes .../Atmos/pipe.rsi/pipeNEBend2.png | Bin 0 -> 255 bytes .../Atmos/pipe.rsi/pipeNEBend3.png | Bin 0 -> 222 bytes .../Atmos/pipe.rsi/pipeNWBend1.png | Bin 0 -> 317 bytes .../Atmos/pipe.rsi/pipeNWBend2.png | Bin 0 -> 347 bytes .../Atmos/pipe.rsi/pipeNWBend3.png | Bin 0 -> 324 bytes .../Atmos/pipe.rsi/pipeNorth2.png | Bin 0 -> 229 bytes .../Atmos/pipe.rsi/pipeSEBend1.png | Bin 0 -> 233 bytes .../Atmos/pipe.rsi/pipeSEBend2.png | Bin 0 -> 264 bytes .../Atmos/pipe.rsi/pipeSEBend3.png | Bin 0 -> 276 bytes .../Atmos/pipe.rsi/pipeSWBend1.png | Bin 0 -> 267 bytes .../Atmos/pipe.rsi/pipeSWBend2.png | Bin 0 -> 292 bytes .../Atmos/pipe.rsi/pipeSWBend3.png | Bin 0 -> 309 bytes .../Atmos/pipe.rsi/pipeSouth2.png | Bin 0 -> 278 bytes .../Atmos/pipe.rsi/pipeTEast1.png | Bin 0 -> 450 bytes .../Atmos/pipe.rsi/pipeTEast2.png | Bin 0 -> 450 bytes .../Atmos/pipe.rsi/pipeTEast3.png | Bin 0 -> 433 bytes .../Atmos/pipe.rsi/pipeTNorth1.png | Bin 0 -> 474 bytes .../Atmos/pipe.rsi/pipeTNorth2.png | Bin 0 -> 447 bytes .../Atmos/pipe.rsi/pipeTNorth3.png | Bin 0 -> 427 bytes .../Atmos/pipe.rsi/pipeTSouth1.png | Bin 0 -> 398 bytes .../Atmos/pipe.rsi/pipeTSouth2.png | Bin 0 -> 416 bytes .../Atmos/pipe.rsi/pipeTSouth3.png | Bin 0 -> 426 bytes .../Atmos/pipe.rsi/pipeTWest1.png | Bin 0 -> 449 bytes .../Atmos/pipe.rsi/pipeTWest2.png | Bin 0 -> 471 bytes .../Atmos/pipe.rsi/pipeTWest3.png | Bin 0 -> 479 bytes .../Atmos/pipe.rsi/pipeWest2.png | Bin 0 -> 236 bytes 43 files changed, 371 insertions(+), 40 deletions(-) create mode 100644 Content.Client/GameObjects/Components/Atmos/PipeVisualizer.cs create mode 100644 Content.Shared/GameObjects/Components/Atmos/SharedPipeComponent.cs create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/meta.json create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeEast2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeFourway1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeFourway2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeFourway3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLateral1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLateral2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLateral3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLongitudinal1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLongitudinal2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLongitudinal3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNEBend1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNEBend2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNEBend3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNWBend1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNWBend2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNWBend3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNorth2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSEBend1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSEBend2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSEBend3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSWBend1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSWBend2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSWBend3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSouth2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTEast1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTEast2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTEast3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTNorth1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTNorth2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTNorth3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTSouth1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTSouth2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTSouth3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTWest1.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTWest2.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTWest3.png create mode 100644 Resources/Textures/Constructible/Atmos/pipe.rsi/pipeWest2.png diff --git a/Content.Client/GameObjects/Components/Atmos/PipeVisualizer.cs b/Content.Client/GameObjects/Components/Atmos/PipeVisualizer.cs new file mode 100644 index 0000000000..7d057e0766 --- /dev/null +++ b/Content.Client/GameObjects/Components/Atmos/PipeVisualizer.cs @@ -0,0 +1,69 @@ +using Content.Shared.GameObjects.Components.Atmos; +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Interfaces.GameObjects.Components; +using Robust.Client.Interfaces.ResourceManagement; +using Robust.Client.ResourceManagement; +using Robust.Shared.GameObjects.Components.Renderable; +using Robust.Shared.IoC; +using Robust.Shared.Log; +using Robust.Shared.Utility; +using System; +using System.Collections.Generic; +using YamlDotNet.RepresentationModel; + +namespace Content.Client.GameObjects.Components.Atmos +{ + [UsedImplicitly] + public class PipeVisualizer : AppearanceVisualizer + { + private RSI _pipeRSI; + + public override void LoadData(YamlMappingNode node) + { + base.LoadData(node); + + var rsiString = node.GetNode("pipeRSI").ToString(); + var rsiPath = SharedSpriteComponent.TextureRoot / rsiString; + try + { + var resourceCache = IoCManager.Resolve(); + var resource = resourceCache.GetResource(rsiPath); + _pipeRSI = resource.RSI; + } + catch (Exception e) + { + Logger.ErrorS("go.pipevisualizer", "Unable to load RSI '{0}'. Trace:\n{1}", rsiPath, e); + } + } + + public override void OnChangeData(AppearanceComponent component) + { + base.OnChangeData(component); + + if (!component.Owner.TryGetComponent(out ISpriteComponent sprite)) + { + return; + } + if (!component.TryGetData(PipeVisuals.VisualState, out PipeVisualStateSet pipeVisualStateSet)) + { + return; + } + for (var i = 0; i < pipeVisualStateSet.PipeVisualStates.Length; i++) + { + var pipeVisualState = pipeVisualStateSet.PipeVisualStates[i]; + var rsiState = "pipe"; + rsiState += pipeVisualState.PipeDirection.ToString(); + rsiState += ((int) pipeVisualState.ConduitLayer).ToString(); + + var pipeLayerKey = "pipeLayer" + i.ToString(); + sprite.LayerMapReserveBlank(pipeLayerKey); + var currentPipeLayer = sprite.LayerMapGet(pipeLayerKey); + sprite.LayerSetRSI(currentPipeLayer, _pipeRSI); + sprite.LayerSetState(currentPipeLayer, rsiState); + sprite.LayerSetVisible(currentPipeLayer, true); + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Atmos/Piping/Pumps/BasePumpComponent.cs b/Content.Server/GameObjects/Components/Atmos/Piping/Pumps/BasePumpComponent.cs index 0099549e84..23e9f63c33 100644 --- a/Content.Server/GameObjects/Components/Atmos/Piping/Pumps/BasePumpComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/Piping/Pumps/BasePumpComponent.cs @@ -1,6 +1,7 @@ using Content.Server.Atmos; using Content.Server.GameObjects.Components.NodeContainer; using Content.Server.GameObjects.Components.NodeContainer.Nodes; +using Content.Shared.GameObjects.Components.Atmos; using Robust.Shared.Log; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; diff --git a/Content.Server/GameObjects/Components/NodeContainer/Nodes/PipeNode.cs b/Content.Server/GameObjects/Components/NodeContainer/Nodes/PipeNode.cs index b35d16280f..ddd2d57c9a 100644 --- a/Content.Server/GameObjects/Components/NodeContainer/Nodes/PipeNode.cs +++ b/Content.Server/GameObjects/Components/NodeContainer/Nodes/PipeNode.cs @@ -1,7 +1,8 @@ using Content.Server.Atmos; using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; using Content.Server.Interfaces; -using Content.Shared.Atmos; +using Content.Shared.GameObjects.Components.Atmos; +using Robust.Server.GameObjects; using Robust.Shared.GameObjects.Components.Transform; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Maths; @@ -23,6 +24,12 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes public PipeDirection PipeDirection => _pipeDirection; private PipeDirection _pipeDirection; + /// + /// Controls what visuals are applied in . + /// + public ConduitLayer ConduitLayer => _conduitLayer; + private ConduitLayer _conduitLayer; + [ViewVariables] private IPipeNet _pipeNet = PipeNet.NullNet; @@ -55,17 +62,24 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes [ViewVariables] public float Volume { get; private set; } + private AppearanceComponent _appearance; + + private PipeVisualState PipeVisualState => new PipeVisualState(PipeDirection, ConduitLayer); + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); serializer.DataField(ref _pipeDirection, "pipeDirection", PipeDirection.None); serializer.DataField(this, x => Volume, "volume", 10); + serializer.DataField(ref _conduitLayer, "conduitLayer", ConduitLayer.Two); } public override void Initialize(IEntity owner) { base.Initialize(owner); LocalAir = new GasMixture(Volume); + Owner.TryGetComponent(out _appearance); + UpdateAppearance(); } public void JoinPipeNet(IPipeNet pipeNet) @@ -128,6 +142,16 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes } } + private void UpdateAppearance() + { + var pipeVisualStates = Owner.GetComponent() + .Nodes + .OfType() + .Select(pipeNode => pipeNode.PipeVisualState) + .ToArray(); + _appearance?.SetData(PipeVisuals.VisualState, new PipeVisualStateSet(pipeVisualStates)); + } + private enum CardinalDirection { North = Direction.North, @@ -136,36 +160,4 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes West = Direction.West, } } - - public enum PipeDirection - { - None = 0, - - //Half of a pipe in a direction - North = 1 << 0, - South = 1 << 1, - West = 1 << 2, - East = 1 << 3, - - //Straight pipes - Longitudinal = North | South, - Lateral = West | East, - - //Bends - NWBend = North | West, - NEBend = North | East, - SWBend = South | West, - SEBend = South | East, - - //T-Junctions - TNorth = North | Lateral, - TSouth = South | Lateral, - TWest = West | Longitudinal, - TEast = East | Longitudinal, - - //Four way - FourWay = North | South | East | West, - - All = -1, - } } diff --git a/Content.Shared/GameObjects/Components/Atmos/SharedPipeComponent.cs b/Content.Shared/GameObjects/Components/Atmos/SharedPipeComponent.cs new file mode 100644 index 0000000000..f588dc44da --- /dev/null +++ b/Content.Shared/GameObjects/Components/Atmos/SharedPipeComponent.cs @@ -0,0 +1,74 @@ +using Robust.Shared.Serialization; +using System; + +namespace Content.Shared.GameObjects.Components.Atmos +{ + [Serializable, NetSerializable] + public enum PipeVisuals + { + VisualState + } + + [Serializable, NetSerializable] + public class PipeVisualStateSet + { + public readonly PipeVisualState[] PipeVisualStates; + + public PipeVisualStateSet(PipeVisualState[] pipeVisualStates) + { + PipeVisualStates = pipeVisualStates; + } + } + + [Serializable, NetSerializable] + public class PipeVisualState + { + public readonly PipeDirection PipeDirection; + public readonly ConduitLayer ConduitLayer; + + public PipeVisualState(PipeDirection pipeDirection, ConduitLayer conduitLayer) + { + PipeDirection = pipeDirection; + ConduitLayer = conduitLayer; + } + } + + public enum PipeDirection + { + None = 0, + + //Half of a pipe in a direction + North = 1 << 0, + South = 1 << 1, + West = 1 << 2, + East = 1 << 3, + + //Straight pipes + Longitudinal = North | South, + Lateral = West | East, + + //Bends + NWBend = North | West, + NEBend = North | East, + SWBend = South | West, + SEBend = South | East, + + //T-Junctions + TNorth = North | Lateral, + TSouth = South | Lateral, + TWest = West | Longitudinal, + TEast = East | Longitudinal, + + //Four way + Fourway = North | South | East | West, + + All = -1, + } + + public enum ConduitLayer + { + One = 1, + Two = 2, + Three = 3, + } +} diff --git a/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml b/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml index 5dcbab768c..da29191613 100644 --- a/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml +++ b/Resources/Prototypes/Entities/Constructible/Ground/pipes.yml @@ -12,32 +12,31 @@ - type: Icon texture: Constructible/Power/eightdirwire.png - type: Sprite - sprite: Constructible/Power/hv_cable.rsi - type: Destructible thresholdvalue: 100 + - type: Appearance + visuals: + - type: PipeVisualizer + pipeRSI: Constructible/Atmos/pipe.rsi - type: entity parent: PipeBase id: FourwayPipe name: Fourway Pipe components: - - type: Sprite - state: hvcable_15 - type: NodeContainer nodes: - !type:PipeNode nodeGroupID: Pipe - pipeDirection: FourWay + pipeDirection: Fourway - type: entity parent: PipeBase id: LongitudinalPipe name: Longitudinal Pipe components: - - type: Sprite - state: hvcable_3 - type: NodeContainer nodes: - !type:PipeNode nodeGroupID: Pipe - pipeDirection: Longitudinal + pipeDirection: Longitudinal \ No newline at end of file diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/meta.json b/Resources/Textures/Constructible/Atmos/pipe.rsi/meta.json new file mode 100644 index 0000000000..92a08111a2 --- /dev/null +++ b/Resources/Textures/Constructible/Atmos/pipe.rsi/meta.json @@ -0,0 +1,196 @@ +{ + "version":1, + "size":{ + "x":32, + "y":32 + }, + "license":"CC-BY-SA-3.0", + "copyright":"Taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da", + "states":[ + { + "name":"pipeEast2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeNorth2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeSouth2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeWest2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeFourway1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeFourway2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeFourway3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeLateral1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeLateral2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeLateral3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeLongitudinal1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeLongitudinal2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeLongitudinal3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeNEBend1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeNEBend2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeNEBend3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeNWBend1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeNWBend2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeNWBend3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeSEBend1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeSEBend2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeSEBend3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeSWBend1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeSWBend2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeSWBend3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTEast1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTEast2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTEast3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTNorth1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTNorth2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTNorth3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTSouth1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTSouth2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTSouth3", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTWest1", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTWest2", + "directions":1, + "delays":[ [ 1.0 ] ] + }, + { + "name":"pipeTWest3", + "directions":1, + "delays":[ [ 1.0 ] ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeEast2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeEast2.png new file mode 100644 index 0000000000000000000000000000000000000000..a44e27011fb9326d40fc0c6046b276c406d6737d GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ1)eUBAr*7pUUK9*qQKMo&^~M7 z1>usb#T7FA*PW+@Ts|5wGxE%-LkA}0FSkiP(olTP@_VvTRKjgDY0LR;(i%$zlHa_R zP~LiN{ZH%a^fu`emdpuhdpFG7sKcFhtWc(dV{4cbM+ZmRw;1N%`}T7!JyJQZHa>Lb zvX{!g=LLp7Xq1e&zV*C=SLZdUwWiN1-9mqRyDq8k?+|d3*n7+J`JCUv;&ILPnZ}_? RFM)1l@O1TaS?83{1OTbgSWf@| literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeFourway1.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeFourway1.png new file mode 100644 index 0000000000000000000000000000000000000000..3da5ae8a6a32ea666f601a0a7a8351c622869dcb GIT binary patch literal 556 zcmV+{0@MA8P)83=p=OXN850f-DIV3XhoNZ^Hj!FwRh zz#D_al2D1|u4?^XZ&lrpVwFlobvhk29*@=6*O#i*YAUVIJ(fueQ0lLqrfHAVy&d2u z$jbqAUH|rdIlz9u2Vl3`y$3)D0f3b9Df=K5K+`m&lqjW0lH~OONs&| ze2(F16MmN9lL?=d2}N4K&+;3`G287nwco8K(*g{`z_x9Q#Ueov;CUX~?e-FgO`&gDmsZ;`>R4QRv7LMa!+cty2fNr;&D*Rgxk)~;0brcE(08akZYDK+Xr&_H7 zP%IYD{(L@m zQ52o;4MGSsO(RJXgb-Kj$tMrIJrAVTf-nqex7!Sd!<&xW!vUm}L{ao`;hO=TZK(jq u7Jsc^8~A*y(Qga)4()O#T2*H{w8|sH$xM0000FA literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeFourway2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeFourway2.png new file mode 100644 index 0000000000000000000000000000000000000000..7c29562995d88e844986568c414a2eb691050f8d GIT binary patch literal 538 zcmV+#0_FXQP)69Bl zs5pI}d}*3;JRX%|=_*dPZR2?!rfCvI5n&i|JRVg-J*NTy`~6<60@Z5up+~t`EMnU> zo6UxHyN&C*IF7?=wPHS>14!GpIUElE2H^YtLpKINfbaVZ1_NBz#j-2_EX%@mU4kIM z^E`&bA^m>;$9T6HqC1ZBFm0t$0pRAd+wEvJo7C%d08G=o@0ZJEq?8CDkWzBFTo6K# zWf_G+;eK78OePNlESF0FCX)%BPKQ>j#df=8u~+~QMG*kg>GZF0bX_M+)34*-{rl01 z#Uf!C62~#?^%{UytHolmxSxk%2*7+kr&KDDBngILkR-`nHwYonG>t6F5JG(B!29Qb z(zhUvW4hfg1viF$63mq?6#^4pLZHS!EkmmRf7?8Z5E_1$)zE0aoe?`~zKrp!u6y$d!8z zM>Lll4+oqk4B?&knPJ{$-HiT?T^z|N49YXfztcaZE0kLs68}IW8890NAz- zz;3srTCGwpmjN&g!uNd?ML|_n;y6Z86p|!)%3RYlJkKKt0@mv_0JU0;`Fwtxd!7e? z@B8SwP8f#d^LfHBy!xfy@}2Rn1OHnGGJ6YxAfVN1F&d5TM($eygb;*bm|B;4Kk#D! zNs^Gy=TTKPRYlFbB~z4i_c}8GRaFr}Af+UZ|WqW}vK{g<8f{AT@Shg;itmx|1J&MDZ~ z@g-^PS3z%0`LDJ2nGWy}TqfG9gVsaEG-E%NZVHX2Hgp2hZ$Sx7xh0TtJZF z%Zqn=H||zm+7iUo_n1L&;We%_Ho=2;cQZy^|N5G<=v+YP3N3~N8TS=hMdxCR>z7ZF zQ@g+Q{j6)#mt}r>CdY8*jbUJP^y%%L?{EEPPh&GaY`_z6_4*Q*zc#s>fiA3Xl4qP; U+8%Xb0?6|Wp00i_>zopr0BQzrkpKVy literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLateral2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLateral2.png new file mode 100644 index 0000000000000000000000000000000000000000..aad6e9f0f6552842ef08d8f81ca99ea1518de52b GIT binary patch literal 278 zcmV+x0qOpUP)ZZQD>)RCN?vYo|ER^S}D*^*ZHLb?Cp*wOupa?{~}$RmI&=RZ>cr86rYTiIfr| z!t?p0l!Ch>A^;=0`)KU$TrL;fo%j2Vh|pRaecXKvAdko6>j`qs)LN;v0#Hh!)=JKK zXpZk`n%MXKYi-zl(Dc4?yG6&dI0&IUmc c1VI4s0lW!#hi}Xr=>Px#07*qoM6N<$g5ZmNFaQ7m literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLateral3.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLateral3.png new file mode 100644 index 0000000000000000000000000000000000000000..e715454f7e8af26a5ed99de403a401fe93f6a52a GIT binary patch literal 278 zcmV+x0qOpUP)w2vm&S3lIz0fW>SLp7Tg}&v@7ntZstQ#_-}exapG}F{d8)IH<2a7v cIL^P|19x|LhZrqd0{{R307*qoM6N<$f;BdBtN;K2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLongitudinal1.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLongitudinal1.png new file mode 100644 index 0000000000000000000000000000000000000000..92bbfb07229c10359577f0320c362b068bdc0eeb GIT binary patch literal 329 zcmV-P0k-~$P)tm41~w|K`7LKsEc}NiN-h~aBRN=%3k3~?0U|Q=94qA1KemFN1Nx_)^)XIS!|jn zyF2qAg}VZ?%THC&b={lZ&j6ZYj5yEJ55UY2WBfgUssgw=-~#X|43A6S1u!$@oIjoT zIRF4KGl&Qx;s@Y%1ub|X1fLG5DoQCJqSwtI0RYz(Y}@8D35f_fXOvQW=Rn&DZUAl> zP*pH90Qk*;oHK|B`@Z`CG`WQ^rQ{dFloD#KUon3K(6*q6_}I$816(0yCr58oLMDO$Y-B^MIK_ zL;xUe4=^)`2*+{60JI1*VJRifgryYR_x)PD8=zf5RgL|SxO>bL48s5s!8neu#Jd4R z1k4;~!dCY4JYxV_gstKx{MLZo06AxrQsTa3s*3x*K}0coptT@u3Q|fC5vXe1IsUKs Y0|NAXo?wf37ytkO07*qoM6N<$f@zP0W&i*H literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLongitudinal3.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeLongitudinal3.png new file mode 100644 index 0000000000000000000000000000000000000000..3666086c91efa4fa1c2c2b437202513983a78f83 GIT binary patch literal 321 zcmV-H0lxl;P)v*$&WweyeV#2@H31i=ymM`t26zHURo^4%M+xOkJZL?)r z>`q+h1<({@#C2V_&vyqfGsGC*2dK3I_^p5oz&Bxdma-dwnSq(Vm3SQh07L{t1Xc9| zaBD#`UI@Xb0<~7;oIym7;<~rs^Z8&HhW7!82+WL}v+o=*yY&V9AAp+&YON3v0Pvdw z%nTyJaU4DXO>QPkDfyW&rG!$-qjB+yQ<7&bW4- T8>8L000000NkvXXu0mjfYe1z-3hs~G0iBhk5GQMsERdjA)nr{(&`CQwIGibL_mw%jV2_IJP6DYE3A zWGqboRegDUu*ln^}F1HdzC5$^VCmo zGB|In6x19#wNNH7blqzwmlKwc=Qz6rT-8!od)AplD)~>i@Ac9<-+3LpUd}wQ{m6T^ zr6OLMJcohY=S!8oR=cn~zi0QqEm5NFqhbwXL$ceU?_&JlfIedIboFyt=akR{0IsfO AjQ{`u literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNEBend3.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNEBend3.png new file mode 100644 index 0000000000000000000000000000000000000000..f861f8b49ebb8d54f17df643aea05262ce7c5b56 GIT binary patch literal 222 zcmV<403rX0P)_*Dz+7tu)*1PcYleS3v>1Kmt@EBDO4xt?Ozz zXA=?oWZk1yz^^>O13Vz!wedX9v~BzLFSsRO7zR>Gs44(W(_G`*1Ga5rnkL3^B!mEf zs$ypJeUF*3?>iv`RFzQka1pVT(pPJ$2AmPE^B5zg6iO*{UB_`8*K?dV;Tvxrvl2HM^l_Gc1LM4X~MXSwR9)K0_6%Ck3R0yuzon$C^7|8D@wv z+Uaz%+wEqT%f<3Mx4Adp;N}cOgb)IU!vR%Y()VWqCd?KM{Cfc+vW);Uqw6}_wq+QG z-wQ}RFtJ$=tW7FG%D}9EaUAKo4q%%_1Q0?%M0h+N+X$H0Y!iC#F*A0%-R}i>@9Fy< zSSJI1?uSzp1!Y;THirIuKL2^4stm(`s*+{dD$W7?@pwd4F*El2Jt9KWG>FLi9H6SI zRmRX?uh)-_@Ao@(T`#(kB*th{l&VSyf#>sya}MX+y8(g4ohK5B#J}JL;&5Sund)O* P00000NkvXXu0mjfHdTp& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNWBend2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNWBend2.png new file mode 100644 index 0000000000000000000000000000000000000000..f88805cd2752e899c2a73ce6bf53fd5015f0426a GIT binary patch literal 347 zcmV-h0i^zkP)Pj2f$jJ8X{f5oK!Wr@O1)Wi~xv89svL$1p2;b znx@YS5D~ohR8^J712fq?Fq6##F-AfN0C_wBUwuGC7=|H_fSGJ2bk3owY&M(E3vkZy zdcA=4H{enR$?Mw#{3YtCV8PyC=?0>fHw;nd1~cW52pYC002ovPDHLkV1k%xl1=~s literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNWBend3.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeNWBend3.png new file mode 100644 index 0000000000000000000000000000000000000000..36061210b829cc5a79bb756b6958642953178026 GIT binary patch literal 324 zcmV-K0lWT*P)^5mO1iF-rfDS0GC49%y-Q$2{d90LB;)5$1WmMqq=P zuMyB%Lqu@9-99g%wZ^)x0M4C&K3cE8k>@#zqBvcKx~^+@?|18;FPNEMzUr-=nUSXH zX>nbaP3cf+Y#~#k zZUx)=DMG=Fp-aE_b<}vh6KmMbdc5#RjFaHPt#0pazwz1BJI!#o!LvdunWy1=^aK^p dNh+S7n4fKOn9xvLR|j-AgQu&X%Q~loCICRvS;qhX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSEBend1.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSEBend1.png new file mode 100644 index 0000000000000000000000000000000000000000..568023bc17326a2bd84532682dfa292da205e4e7 GIT binary patch literal 233 zcmV z)+`{#XyZ86*dJQ5`7jLV`yMH!=L0@cN?6ww(=@dS0Dyhpv27dXd44`XL_iYDvLNSN zJiK?p-2&CGF6s9H*L48^NTTbyb^&GvlFtXIDpa+~>5BqL;yh1?NSh}Rc@MlF@`FYpp$WZO38dDamCIM0)P-&vOBdjVq%BEq_^9LG^~ zpKQsH_tnMK2|UjOfQaCn(-X)!BO>1mbX^BP-}hDF#R4fM;I9D{fw%VSx^x6yjH&uc z$_3uw+6!1L;GDyIkF`|=mJ5go_kClG(b)s<5vaWaYb_}yL_}v1{U<*`a!fn|9a>`m O0000>+DR0K-y=XvS~ z6o~59iVU3`M^KNJvaT0it9FW?~vzdPbn2&K^+FWC0XGt~f<^)sezLaenoe{*z-XfFKBh zAPB<0LwTON(D1sh#4QlFZ5tf!y3TP+&^V4k6PV{2#u)T{k7ZfdB;sKhPD4%8psFeu zW4L-h0@F184AgZEtu@NBWG@GR`0P!UQm!Zp9LI5qfI18KV&{U7g;zkScZ7%#MbZ5N z-xJvP{eFQoO<}D?mSybaK?2rVBuVnz4*0Qe+xCorhlu?f2ovzdS1cd^ya2ZHO8p5> RTMz&M002ovPDHLkV1i(-ZOi}w literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSWBend2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSWBend2.png new file mode 100644 index 0000000000000000000000000000000000000000..7ea0ed3efe66ea02591f871c50259e75e7972203 GIT binary patch literal 292 zcmV+<0o(qGP)=db=l__~pYqt?dO!Boc{4 zA~K>ZOV9bhaU6n^*L~k}@)(A}b0ow(&*TYg+XiC{#&N{H?<5I5O%tiS>pC<|17i#+ z{}EW0<>ye_wpiB{bzQT{0YFpEPfF>ls=|HWYyn9Lg<|hn4~Q-xk!4xDI}pZxo@X3^fDo+T09_yyb1xuSKq&>S_2)T0F5sNQ qbzSlHKsbV^o6uSd=Ukjc^iN)OL0tX@#x~ag0000&ht!S-ZTxCWkFR{UUkwZFrUOZcV$`PJWszm3UdH&W9R%LMFzn6PbdI z{GNcd_IZFT%b>MJp66b5WB^)gBuNr31J~G(;|K$Ai7~&eCIh&PeF8`dAcTOF^1Y6a z132ekj6s^FVE|$XV+gIaFvf&CM%NbvJ;z#WSZl*v!@ueUTtjRKn}bZ@00000NkvXX Hu0mjfGdq5h literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSouth2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeSouth2.png new file mode 100644 index 0000000000000000000000000000000000000000..ba98a658412034f4c6fcd36e9921cc65eddb370f GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=cRgJkLn`LHy>@zSi-Ca4#ZT;< zog5JpB{xnGTc~*ZOZ3NW#zxm7I;xo*o;Ky_FamWjFw`W@OOL*O^;_-s+}k;kVz1|} zoVNdWgMd@F%-s-if#fMSljHyFU&WNvbINl2xl690jL$2*CV6STmuXzhU>vNuG;=}x zYOMqr_oY)ze1l)x*oTKYczGT+*i+6KH~(*;jPKzu1+V2E%*md*c=jr$b{`MY_%H}89IhW8*vN-5Lp^~`FuGUM^sD5XqV%p)r0d07Ea02BZPKmkwy z{7V3l=1{NKKds*&2vXy+>Lty=aU43G4$Wqh^ZCqVG9d_pyz-}aKq+M`%X&X+tvMc# z&+7ny=XrFyUAEgTzVBmMmT?@1!{LC|8Yv}F6agTFz!-xNf^xY`9LE5kY(fa`_j@*g zMAd4QcDv1dK4&l(FdB^*4u_8x{Xv-lcDo&}>r$)L0H{wIzR1u;J2IE_W z<~GPdTsk6BmrQ(Uh{Z7*lxFP`~UAb(CKuzTrSM#^Y6}qPc~rn7AU2N z9AeD_bu(7h#-V=BMweSiaK#No!K)iwx!77Md91XKo zwpqbH%tl!9>jLjhKD-$w0Yi~e>Rzv>SF4pCkH=a{sh{byOab0a3HUfbm|Cb_um3u9 zaU4Hf|H~A>_kB8@4$Wqh^ZCqVG9ixRhkeE-Af?ofb|@42Q$JwZ;Lv-Hsp# zsMTr!R4Nq!8jS{?=aHrEao0bsFM+^zqUEl84tD2f1B zE|=VHH`eR*-P-?m542h>PNx&o>9p8;;N1xr`xYpr2*Z%sY(~G|f4a{Yz;#^!JkNWn z&luo(y#k>1Q$IrH0a=y-aJgJQ1IQ!9YvNt4 bKneH;=X8buZS$qC00000NkvXXu0mjfN>slR literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTNorth1.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTNorth1.png new file mode 100644 index 0000000000000000000000000000000000000000..e082a773c521a04fe3e80e77f06a11c6195ce0aa GIT binary patch literal 474 zcmV<00VV#4P)zkWi9Dt+Gv&@>Gx zB}yr>Ec<7Z&x%pcFk0a1Dtsa19klFxhYeFey-h{OPG)?#nQX4>RP54l4 z6)+6rzw569TrL*?&gb)w0F)l=^XE5BQ{p(TtRZCC0^7FnJP*?}3B!=pYDFB!Rr!Bj z0f5u#R9ywS-R_HluIt#g&EarhG#cT$E{@}{-|yLMHUP@DZK5dp$Sg^cR{-DlUmgZQ zfbaWEr&CwHqd@cKa_vrd60SondJu@DU&3e5y^ZDEi1_NW`1JJTbGUl_M5W=?ZYXDM8 z9LK>JLs^zT4^WmRT5BGU$4kYn0iI7FrF;*-caXOMyln`ddRqrP&-=3eIKbs{0pNT- zzYJjYh~K|_T5F1;u<~+jlEN?~j$?e^C(ANcs})62*jW9W4gj1^C%X=GyWLu&?7A*t z7;-oq7>!0KrHG=4{eI78vjH$+7?S7t-vJ~^QtM)xrX)$ibUH;TMGyo41VMmOiZo4$ zUsQ zX|-AiA#fIpMQwoHZU?}xIos{FinA;OV7XlW(aUihwAKil8Tj3Kp6A?dH$2bde!o}0 pYbj+F3n9Mj8#QXws8OT;TOVTLladQp=YaqK002ovPDHLkV1j&q!x;bo literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTNorth3.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTNorth3.png new file mode 100644 index 0000000000000000000000000000000000000000..278065543805d59093a08c7e7d47f413d8167c6c GIT binary patch literal 427 zcmV;c0aX5pP)1u%DFqi&x+(+}Z&2_GxrQs3b*+0((Gv(BKo=gsRrLm<&>lh1+K^ccmh0mpGFB?m~7 zgz0q3Y&JtFMGyo41VMmOiX=&hA%wtnUE0g#^4(3lO<9(elLPGcdjLMJv)k<+{WMJh zSglsy>O~la2425V$8peFSFXUvJMddP%QA|h!1Fxr_d8l^px$v?EEbE!VzF5Mj290- VevZy+xB&nF002ovPDHLkV1nFl!yNzs literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTSouth1.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTSouth1.png new file mode 100644 index 0000000000000000000000000000000000000000..04e434edcf583b539ae5311c4a885643c0c3b7a9 GIT binary patch literal 398 zcmV;90df9`P)XXsgTY`h{C9+H+ZsShNxfbtO;aq(!f_l9hXd#HxvA@lj1XY%i$27>`wYZ{FPLI_T$69B&N1JLjH0od(!xUPE@ z==FLx`B&t5j+F9x>yP_9&rwkn6*eYG0>E;)WH=n+x-R?up7nYS!0~vz=08DnIvrgU zT>gOPc?3Z~x7%g2*|1uz*lxEE{Q=9e$_2^_iUi|0F7101RaW3Q4q+JL`#wpMFr7|` zfkuR#u>tVl)~to6Q)H$9LcSB?1>(trh^yX7g_Z(lotUe_cR` s%AWl>fh@~jBJ!|6t@d6jrL0uo4MnYsg)Gj^82|tP07*qoM6N<$f&uKb_W%F@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTSouth2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTSouth2.png new file mode 100644 index 0000000000000000000000000000000000000000..21517957ee65e2a4775e59d26b1b993db62d2697 GIT binary patch literal 416 zcmV;R0bl-!P)OP5lXBaof^a=DZvP>movdDe-q3q1ZsneqcaM4E#pqyv%w0000< KMNUMnLSTYQjhnF6pce8s z>@s2Yo0&ghp;W0--!5UArdCQ3$1z%K0B-j}h;%Kbq*|>KMG=N!U|AO1?UuvgaQ6Vm zasG{~(P)&Lem0xoc^=d0lzVxy;sC1K?E-K*osd$dm0s>I*R@&=Aq4yV9st*M0Z8(! z*K2IsP60Zd&Q<&ufbaV`>pv?DLjZi=r`PLY+culchQ(q5z;3rojKLZd&(be UhgK-)2><{907*qoM6N<$f@hS%E&u=k literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTWest1.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTWest1.png new file mode 100644 index 0000000000000000000000000000000000000000..4711725c00f718863b516da82e5a9822933a6092 GIT binary patch literal 449 zcmV;y0Y3hTP)1v$8q zv)SNz9**PCZnv4w=M0BKUEUu6zVBZ(P9_sttrp|)m}awyZQEK+F97QGI)-7Ol)|#C z^J%ZuY5-KLRRGrO_3r>or_-AqyWI|e)oO)p+qkaFcDvON5QgD7uq=xtNia>5!C(MD z7=}2GL%CemZVq?c0wIL@{wtDF636l5>VW5Y^m;uCg#ydvk{}3(<5-vf^XowBTOg&R r(P%IljqrW{{4aPIz;EjX@B(-TD(#09_jH%d00000NkvXXu0mjfjk(6( literal 0 HcmV?d00001 diff --git a/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTWest2.png b/Resources/Textures/Constructible/Atmos/pipe.rsi/pipeTWest2.png new file mode 100644 index 0000000000000000000000000000000000000000..bf87ae1f255953d5cdf98e443651ca6fde7b0a27 GIT binary patch literal 471 zcmV;|0Vw{7P)&Rh&%Al77Pe!1S=s7N#+$7 zd_3;uKA2qe6*<++Fz0tZ&Y3wgpkc1-s^M^`w%e_m&1TAR9HpZJ@JrVbAkT9EvMkfq zCkR*w=hN0u+ zy6&gqM^U7uRnc*3wOULj6B>;M$K#PO42hyhN9sSwz*k~lS(>JJp2zii#rJ(2$6+uS za5x-TEEYPkKLEz#G4StZvR<$0_xr3?D|)>iwry(%{RZ9E?49)j_6h%QwNtR`(s*05Iuh$I2`25;CoeluL?*nkTT#5l~Hk*$FO(RK? z!WrD}cL2`kGp1?cx-PfdEkD41zeh@ms;Z=E`mK~cv;Hc>Fo@$AUDuh<=K$<>J8avg z-EJ33ptQfhvMj0V`scY2f+&i9t`2yf$8jgpxy4^0z z<&x28gb*T^uk>bAR24u4Pyti`{|~^|P6!|SiysAeD$6n;{}!)wfage-cSfv+)87u} Vr8{6D!n^`#DJ&m;q*tI ztz`x_&E=o?=ACHXS@iZ=)5(zMyPYp-I&^)=WchGep4E{YO5^bf{3~ zN>pLF%Py(<*o4^Y^38LM*P2FUGhB(vTsyIN-*cPIaz;GOyZ7&FoXPkhF8J#1fA@CI k-1z?YdmC4f#rd_2jcc79uCv~c1UjF=)78&qol`;+03%{(U;qFB literal 0 HcmV?d00001