Jump to content

[WIP] [1.12.x] MOARdV's Avionics Systems - MAS Interactive IVA! (v1.3.7, 7 April 2023)


MOARdV

Recommended Posts

36 minutes ago, MOARdV said:

I did not make changes related to them, mainly because I lost track of them (I was in the hospital for an extended period a month ago).  I will try to get a GitHub issue opened with a link to your info so I can set some time aside to reproduce and diagnose the issue.  It may also be worthwhile to look at them again with the updated MAS.  FWIW, I did recover a vessel through MAS without any odd behavior, but that was not specifically at the launch pad.  That's a quick one for me to check locally, however.

Thanks for your reply and I'm glad that you're out of the hospital.

By the way, for some other obscure IVA bugs, I did report another one with regards to the ASET Props DSKY display, at least as used in the ASET retro-style Mk1 Lander Can. Namely, the time to Descending Node with respect to the equator and to a target was wrong, but the AN was correct somehow. I haven't checked if this happens when MAS is installed, but maybe MAS somehow inherited this bug from RPM so you might be interested in checking it out. It's worth noting that the AN/DN times given by the stock game match that given by KER, but KAC was slightly off, and the values displayed by the DSKY displayed another, but different, incorrect value. I looked at the RPM source code and I couldn't figure it out, but on a historical note, I'm pretty sure I found something from the very beginnings of KSP itself: https://www.physicsforums.com/threads/position-of-ascending-and-descending-nodes.534665/

Spoiler

  

On 4/14/2022 at 11:58 AM, minkar81002 said:

Hello. In using the DSKY from the Mk1 Landing Can replacement IVA and other retro-style IVAs, I have discovered that the time to equatorial Descending Node (DN) and to target Descending Node is incorrect both with respect to the displayed DN marks on the Map Screen and also the Orbital Readouts in Kerbal Engineer Redux. However the time to both equatorial AN and with respect to target AN are correct and match those in the Map Screen and KER.

I did some sleuthing and found that the DSKY uses the RPM variables TIMETODNEQUATORIAL and TIMETODNWITHTARGETSECS. These are then handled in RasterPropMonitor\Core\RPMCEvaluators.cs; these then make calls vessel.orbit.TimeOfDescendingNodeEquatorial( ) and vessel.GetOrbit().TimeOfDescendingNode( ) which are located at RasterPropMonitor\Core\OrbitExtensions.cs. These then make the calls o.TimeOfTrueAnomaly(o.DescendingNodeEquatorialTrueAnomaly(), UT)  and a.TimeOfTrueAnomaly(a.DescendingNodeTrueAnomaly(b), UT). Those functions are handled in the same OrbitExtensions.cs library; they handled at Core\UtilityFunctions.cs. While AN variables are calculated with

public static double AscendingNodeTrueAnomaly(this Orbit a, Orbit b) {
            Vector3d vectorToAN = Vector3d.Cross(a.SwappedOrbitNormal(), b.SwappedOrbitNormal());
            return a.TrueAnomalyFromVector(vectorToAN); }

and

 public static double AscendingNodeEquatorialTrueAnomaly(this Orbit o) {
            Vector3d vectorToAN = Vector3d.Cross(o.referenceBody.transform.up, o.SwappedOrbitNormal());
            return o.TrueAnomalyFromVector(vectorToAN); }

the DN variables are derived from the AN with:

public static double DescendingNodeTrueAnomaly(this Orbit a, Orbit b) {
            return JUtil.ClampDegrees360(a.AscendingNodeTrueAnomaly(b) + 180); }

and

public static double DescendingNodeEquatorialTrueAnomaly(this Orbit o) {
            return JUtil.ClampDegrees360(o.AscendingNodeEquatorialTrueAnomaly() + 180); }

The JUtil.ClampDegrees360() function is located at Core\UtilityFunctions.cs and works as:

public static double ClampDegrees360(double angle) {
            angle = angle % 360.0;
            if (angle < 0)
                return angle + 360.0;
            return angle; }

After all this, I don't see why the AN calculations could be correct but the DN ones could be incorrect. I was hoping to find an error in the calculations somewhere, but I really am not seeing anything wrong with the DN calculations. Can anyone else figure it out? :huh:

It'd also be good to find out why the time-to-impact calculation is giving wrong answers. Without MechJeb installed, this calculation appears to happen with FallbackEvaluateTimeToImpact( ) at Core\RPMVCEvaluators.cs. Again, I don't see what could be wrong but maybe there's something different about altitude as of adding the terrain height display in KSP 1.7.

 

And then if you scroll up, I also noted that the time-to-impact was wrong for RPM so I guess there's another calculation that went awry.

Spoiler

  

On 3/29/2022 at 1:23 AM, minkar81002 said:

Hello. I have noticed a bug which I think might be due to Raster Prop Monitor.

I installed Raster Prop Monitor, but when I noticed that it doesn't include any IVAs, I installed DE_IVAExtension, which also requires the ASET Props Pack.

In the Landing screen, the estimated Time to Impact is broken. The configuration file for this screen is located at: GameData\ASET\ASET_Props\MFDs\ALCORMFD40x20\ALCORLanding40x20.txt . The relevant line is:

{2:"";"                                        ";""} [#{1:00FF00FF;FF0000FF;FFFF00FF}]{1:"ASCENT                                     ";"!DESCENT! ";""} [#FFFFFFFF][font0]Est.TI:[#FF8000FF]{0:METm:s.f}[#FFFFFFFF]sec $&$TIMETOIMPACTSECS VERTSPEEDROUNDED  ORBITMAKESSENSE

So, it looks like there are calls to Raster Prop Monitor with the variables "$&$TIMETOIMPACTSECS VERTSPEEDROUNDED  ORBITMAKESSENSE". My guess is that these calls are broken somewhere in Raster Prop Monitor. Maybe something got messed up once KSP changed the landing display to include the possibility to show terrain height.

 

Anyway, thanks for your service. I especially appreciate your wiki guide on how to read the FDAI, ARRT, DSKY, etc.

Edited by minkar81002
Link to comment
Share on other sites

14 hours ago, minkar81002 said:

By the way, for some other obscure IVA bugs

I'm a little confused - you mention RPM as well as MAS.  Are these bugs in RPM, or they bugs in MAS, or both?  I'm not involved with RPM in any way (haven't been for a few years), so I won't be looking at RPM issues.

Link to comment
Share on other sites

2 hours ago, MOARdV said:

I'm a little confused - you mention RPM as well as MAS.  Are these bugs in RPM, or they bugs in MAS, or both?  I'm not involved with RPM in any way (haven't been for a few years), so I won't be looking at RPM issues.

If I'm not mistaken, MAS has newer versions of most props used by RPM. So pretty much I'm just saying that there are these obscure bugs out there, such as the time-to-DN not being displayed correctly by the DSKY prop, so there's a chance that these bugs may have made their way into MAS. I'm not currently using MAS since I uninstalled it after having issues, so I haven't checked if these bugs are in MAS. I'm just bringing it up in case you're flying a mission that uses the DSKY prop sometime, and if you remember, you could see if the time-to-DN information is correct or not.

Link to comment
Share on other sites

2 hours ago, minkar81002 said:

If I'm not mistaken, MAS has newer versions of most props used by RPM. So pretty much I'm just saying that there are these obscure bugs out there, such as the time-to-DN not being displayed correctly by the DSKY prop, so there's a chance that these bugs may have made their way into MAS

In this case, you are mistaken.

MAS is a completely separate mod than RPM.  It has some common code because orbital mechanics and the interface with KSP are the same, but it is not as simple as a newer version of the props.  The props (the actual models) are identical.  The difference is how the mods make the props work, and what the mods are capable of doing with those props.  A bug in RPM does not automatically mean MAS has the same bug.

Link to comment
Share on other sites

On 5/1/2022 at 11:20 AM, MOARdV said:

And MAS v1.3.2 is now up on GitHub.  This is another point release to fix the wrong-sized world maps @Sesshaku reported, plus (hopefully) the rest of the multi-mode engine fix for @Manul

There is also the beginnings of a prototype general-purpose touchscreen MFD prop for anyone wanting to live on the ragged edge of MAS technology.  It doesn't do much, and you definitely don't want it to be your only prop (yet), but it'll give you a peek of the UX I'm going to try to work with.

 

CJvQRp.jpg

EDIT: And, if anyone wants to provide feedback or suggestions for what the touchscreen MFD should do, the left MFD shows all of the pages I've thought of so far.  Feel free to provide suggestions for what sort of pages I should add.  The ideal goal is that just about everything can be controlled from the MFD.

I can't read the last one, the one on the third column (starting from left to right).
Other than that, like I said before, the feature I need the most for attempting a full IVA with no game interface, is a way of interacting with Mechjeb S.A.S.S, specially for pitch head and rolling. I don't know if that will be included in the current SAS panel, but that Is the feature I wish the most. And is also a feature that would work well in a touchscreen I think, you just have to copy the mechjeb S.A.S.S tab on it and let the player press plus or negative buttons.

I also support the science panel idea, to controll all experiments from there. I don't know how easy that would be, considering there are mods like kerbalism that modify science (I know kerbalism has a science control panel in their interface though). Other than that I think most of the panels cover everything major. Next time I open KSP I'll try making a full IVA moon mission to see if I can think of anything else that would be useful.


EDIT: Just read you were at the hospital. Wish you a fast recovery!

Edited by Sesshaku
Link to comment
Share on other sites

5 hours ago, Sesshaku said:

I can't read the last one, the one on the third column (starting from left to right).

"WBI" - Wild Blue Industries.  I added support for @Angel-125 flying saucer mod a while back, and I intend for the new touch screen to support it.  Right now that's a placeholder button, until I come up with a name that makes it more obvious what it does (or maybe I need a caption for it).

Link to comment
Share on other sites

MAS is now updated to v1.3.3 on GitHub.  This update is strictly a data update - the DLL is unchanged, other than the version.  However, thanks to @Manul, the map views on the MFD2 MFD include maps for Dres, Duna, Eeloo, Eve, and Laythe.  In addition, the TS1 touch-screen MFD now has a nearly-complete Flight page:

ixrukX.png

The Flight page is documented on the GitHub wiki here.

Link to comment
Share on other sites

22 hours ago, Jaxx said:

what was the target file path for the message log the mod mentions when it throws an error?

The game installation directory.  KSP.log contains additional information about any errors MAS reports.

Link to comment
Share on other sites

@MOARdV So I've successfully made a seperate model of the ALCOR power seat. It all works in-game, *except* I cant figure out how (or if its even possible), to tie *different* kerbals to different seat props... ?? vOv

Please PM if you get a chance ;)

Edited by Stone Blue
Link to comment
Share on other sites

Place an empty gameobject and parent it to the seat, center it on the X and Y axis and lower it roughly at the base of your seat model, orient it Z+ to forward and Y+  to up IIRC. Name the gameobject something unique (Say, MySeatTransform) and reference it from an InternalSeat module within your INTERNAL config, eg:

MODULE
{
	name = InternalSeat
	seatTransformName = MySeatTransform
}

This will attach the Kerbal to the seat transform.

Link to comment
Share on other sites

17 hours ago, vulkans said:

Place an empty gameobject and parent it to the seat, center it on the X and Y axis and lower it roughly at the base of your seat model, orient it Z+ to forward and Y+  to up IIRC. Name the gameobject something unique (Say, MySeatTransform) and reference it from an InternalSeat module within your INTERNAL config, eg:

There is an easy way: the SeatV2 prop already includes a transform that moves together with the seat. It's name is MK1CockpitSeat
I replaced a stock seat with SeatV2 and changed the seatTransformName and it worked (tried it with RPM/ASET but it should work with MAS_SeatV2 as well)

    MODULE
    {
        name = InternalSeat
        seatTransformName = MK1CockpitSeat
        portraitCameraName = Camera_Left
        allowCrewHelmet = false
        kerbalEyeOffset = 0, 0.02, 0
        displayseatName = #autoLoc_6002193
    }

But it works only for a single Kerbal and a single seat. If there are more Kerbals and more seats there is no way to define which transform each seat is assigned to.  Or is there?

Link to comment
Share on other sites

20 hours ago, Stone Blue said:

It all works in-game, *except* I cant figure out how (or if its even possible), to tie *different* kerbals to different seat props... ?? vOv

I guess the answer will be no because MAS is only responsible for moving transforms not for renaming them. But if you have a Unity project for this seat, you  can make as many seat props with unique transform names as required. Like commanders_seat, copilots_seat, engineers_seat and so on.

Link to comment
Share on other sites

1 hour ago, Manul said:

But it works only for a single Kerbal and a single seat. If there are more Kerbals and more seats there is no way to define which transform each seat is assigned to.  Or is there?

Exactly... this is the problem. And so far I've tried adding up to 4 uniquely named transforms to the model, but it just stacks 4 kerbals in the first seat. I've thought about this, and I mostly understand what is going on, what *needs* to happen... but every way I can thin to address it is a no-go. :(

This is most likely the issue AlexUsatas ran into, and why the seat is embedded right in the ALCOR IVA model, instead of being a seperate prop.

47 minutes ago, Manul said:

I guess the answer will be no because MAS is only responsible for moving transforms not for renaming them. But if you have a Unity project for this seat, you  can make as many seat props with unique transform names as required. Like commanders_seat, copilots_seat, engineers_seat and so on.

Yup... thought of that too. That would be the *easy* way... but would mean many different different models, cfgs & or MM patches, with the only difference being a single digit in the seat transform name. I'm trying to avoid that, but that may have to be what happens... We'll see... I'm still poking the issue.

Edited by Stone Blue
Link to comment
Share on other sites

2 hours ago, Manul said:

Or is there?

What if MAS had a module like MASInternalSeat that could be added to a prop seat?  You specify a transform in the module config, like "Mk1CockpitSeat", and MAS will go through and create a child transform with a name like "Mk1CockpitSeat_1" for the first prop in the IVA, "Mk1CockpitSeat_2" for the second, etc.  They'd be numbered in the same order that they show up in Unity, so if you want seat 1 to be the middle seat, you'd place it earlier than the other two seats.

Note that I don't know if this would actually work - KSP might need the transform to exist before MAS has a chance to create it.  But I might be able to whip up a prototype for it this weekend.

Link to comment
Share on other sites

14 hours ago, MOARdV said:

What if MAS had a module like MASInternalSeat that could be added to a prop seat?  You specify a transform in the module config, like "Mk1CockpitSeat", and MAS will go through and create a child transform with a name like "Mk1CockpitSeat_1" for the first prop in the IVA, "Mk1CockpitSeat_2" for the second, etc.  They'd be numbered in the same order that they show up in Unity, so if you want seat 1 to be the middle seat, you'd place it earlier than the other two seats.

Yes exactly...  It would be no problem to put a slew of transforms (uniquely named), right into the single model. I've done it, so did Alex. The issue is that there is no way to rename them via MM patch.
This would sort of be along the lines of being able to index, or have unique 'moduleID =' type of keys, to target/pinpoint, specific instances of a prop, and not *all* instances of the same prop? ....or another, would be to at least allow transformName keys, both types/instances should allow targeting by MM patches?  I was thinking it would be nice (and probably the best way(s) ) to have either, to provide an easy, & flexible way for peeps to interact with/edit/target specific props, as one way to address the issue vOv I imagine if you could get something working for the seat example, it could be used for a ton moar use-cases? vOv

It would be no problem to put a slew of transforms (uniquely named), right into the single model. I've done it, so did Alex. The issue is that there is no way to rename them via MM patch. The patch would have to target

Also, I should be able to get everything I have for the power seat as a test release, up on either github or my googledrive, today or tomorrow, if you want to use it to test your suggestion above, with, @MOARdV vOv

I expanded its movements, with a couple more buttons: Rotate *Left*, as well as *Tilt Back*.. ;) ... initially set for 5° tilt back, which pivots kerbal view upward...

Also, another thing I'ld likke to ask... is there currently a way to have animations *partially* play... say only while a button is "held down"... ??

Edited by Stone Blue
Link to comment
Share on other sites

Quote

is there currently a way to have animations *partially* play... say only while a button is "held down"... ??

A TRIGGER_EVENT on the button would work,

TRIGGER_EVENT
{
	name = Animation Blend
	event = fc.AddPersistentClamped("Global_Animation_Blend", 0.01, 0, 1)
	variable = fc.GetPersistent("%AUTOID%_Trigger")
	autoRepeat = true
}

On the same button's collider you would just toggle %AUTOID%_Trigger on push and toggle it off on release,

COLLIDER_EVENT
{
	name = Button Collider
	collider = MyButtonCollider
	onClick = fc.SetPersistent("%AUTOID%_Trigger", 1)
	onRelease = fc.SetPersistent("%AUTOID%_Trigger", 0)
}

Then connect the animator to Global_Animation_Blend,

ANIMATION
{
	name = Cool Animation
	animation = MyCoolAnimation
	variable = fc.GetPersistent("Global_Animation_Blend")
}

TRIGGER_EVENT will add 0.01 to Global_Animation_Blend every FixedUpdate, clamped between 0 to 1 since ANIMATION blends between those two values. It will fire whenever %AUTOID%_Trigger evaluates to 1. If you want to play the animation backwards, you could add an additional TRIGGER EVENT or a variable that toggles between -1 / 1 and use that to multiply and flip 0.01 to -0.01. 0.01 can be adjusted to determine how fast ANIMATION will blend through the animation.

Edited by vulkans
Link to comment
Share on other sites

@MOARdV So, I'm looking at the MAS Wiki, and I see the Prop Config Tool section mentions that multiple models can be combined, in specific instance of a prop? (If I'm understanding that correctly).
So, if thats the case, say for this seat prop, could I have several .mu's, that only contain a single, uniquely named empty seat transform (kerbal spawn point, basically), and specify in each instance of a seat prop, which .mu to "combine" with the basic seat prop, so that each instance gets its own uniquiely named seat transform?

It seems like, for IVAs that would have multiple seats, that would get around the issue of needing to have uniquely named seat transforms for each instance of matching a kerbal to a seat..??

Edited by Stone Blue
Link to comment
Share on other sites

20 minutes ago, Stone Blue said:

So, if thats the case, say for this seat prop, could I have several .mu's, that only contain a single, uniquely named empty seat transform (kerbal spawn point, basically), and specify in each instance of a seat prop, which .mu to "combine" with the basic seat prop, so that each instance gets its own uniquiely named seat transform?

Yes, that's correct.  That's how the modular switch props work (as well as the touch screen MFDs).  There's a .mu that contains the visible mesh, and another .mu that contains a collider.  I don't see why you couldn't do the same thing with seat transforms.

Link to comment
Share on other sites

  • 2 weeks later...

@MOARdV I am getting weird numbers when I use IAS for airspeed. They are quite a bit higher than what I get when I use the IAS readout in the FAR GUI. I think your formula for calculating IAS may be wrong. It at least appears different than the calculation FAR uses. It appears FAR takes the sqroot of density * pressure ratio, and you take srfspeed * Sqroot of density * pressure ratio. If you would please take a look. Happy to test any changes.

Link to comment
Share on other sites

  • 1 month later...
14 hours ago, Angel-125 said:

Do you have a conversion guide from ASET RPM to MAS? I would like to convert a prop from ASET Exploration Rover System called the PitchRollDisplay:

Oh, that's a cool prop.  I knew I had seen some rover HUD props somewhere, and I couldn't find them in the main ASET prop sets when I wanted to play with rovers.

Looking through the prop config, it's also one of the more convoluted designs.  I'll need to dust off some of my RPM memories to figure out how best to get that converted.

Link to comment
Share on other sites

20 minutes ago, MOARdV said:

Oh, that's a cool prop.  I knew I had seen some rover HUD props somewhere, and I couldn't find them in the main ASET prop sets when I wanted to play with rovers.

Looking through the prop config, it's also one of the more convoluted designs.  I'll need to dust off some of my RPM memories to figure out how best to get that converted.

Much appreciated, thank you. :) Would it be easier for me to just make a new HUD prop? If so, could you point me in the right direction to link up the text displays to the right modules in MAS? I've not made a MAS prop before but I'm willing to give it a try. :)

Link to comment
Share on other sites

@MOARdV I think my part config might not be correct for the latest version of MAS. I have 1.3.3 installed. I'm getting this error during start of the game:

[EXC 15:12:36.836] UnityException: Internal_CreateGameObject is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead. Called from MonoBehaviour 'MASFlightComputer' on game object 'wbiBuffaloCommandPod'.
See "Script Serialization" page in the Unity Manual for further details.
	UnityEngine.GameObject..ctor () (at <12e76cd50cc64cf19e759e981cb725af>:0)
	AvionicsSystems.MASFlightComputer..ctor () (at <177a2c548c7640c9bc351c4169da46e0>:0)
	UnityEngine.DebugLogHandler:LogException(Exception, Object)
	ModuleManager.UnityLogHandle.InterceptLogHandler:LogException(Exception, Object)
	UnityEngine.GameObject:AddComponent(Type)
	Part:AddModule(String, Boolean)
	Part:AddModule(ConfigNode, Boolean)
	PartLoader:ParsePart(UrlConfig, ConfigNode)
	<CompileParts>d__56:MoveNext()
	UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
[EXC 15:12:36.840] NullReferenceException: Object reference not set to an instance of an object
	PartModule.Awake () (at <cd473063d3a2482f8d93d388d0c95035>:0)
	UnityEngine.DebugLogHandler:LogException(Exception, Object)
	ModuleManager.UnityLogHandle.InterceptLogHandler:LogException(Exception, Object)
	UnityEngine.GameObject:AddComponent(Type)
	Part:AddModule(String, Boolean)
	Part:AddModule(ConfigNode, Boolean)
	PartLoader:ParsePart(UrlConfig, ConfigNode)
	<CompileParts>d__56:MoveNext()
	UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
[ERR 15:12:36.841] PartLoader: Encountered exception during compilation. System.NullReferenceException: Object reference not set to an instance of an object
  at PartModule.ApplyUpgradeNode (System.Collections.Generic.List`1[T] appliedUps, ConfigNode node, System.Boolean doLoad) [0x00029] in <cd473063d3a2482f8d93d388d0c95035>:0 
  at PartModule.Load (ConfigNode node) [0x000f9] in <cd473063d3a2482f8d93d388d0c95035>:0 
  at Part.AddModule (ConfigNode node, System.Boolean forceAwake) [0x0006f] in <cd473063d3a2482f8d93d388d0c95035>:0 
  at PartLoader.ParsePart (UrlDir+UrlConfig urlConfig, ConfigNode node) [0x00f10] in <cd473063d3a2482f8d93d388d0c95035>:0 
  at PartLoader+<CompileParts>d__56.MoveNext () [0x00685] in <cd473063d3a2482f8d93d388d0c95035>:0 
	UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
	ModuleManager.UnityLogHandle.InterceptLogHandler:LogFormat(LogType, Object, String, Object[])
	UnityEngine.Debug:LogError(Object)
	<CompileParts>d__56:MoveNext()
	UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
[ERR 15:12:36.841] PartCompiler: Cannot compile part
	UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
	ModuleManager.UnityLogHandle.InterceptLogHandler:LogFormat(LogType, Object, String, Object[])
	UnityEngine.Debug:LogError(Object)
	<CompileParts>d__56:MoveNext()
	UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

My config for the flight computer is:

	MODULE:NEEDS[MOARdV/AvionicsSystems]
	{
		name = MASFlightComputer

		gLimit = 6.7
		baseDisruptionChance = 0.20
		requiresPower = true
		powerOnVariable = 1

		PERSISTENT_VARIABLES
		{
			MAS_IMP_Mode_Select = 1
		}

		RPM_COLOROVERRIDE
		{
			COLORDEFINITION
			{
				// 'white' label unlit color
				name = ASET_SWITCHER_NAME_ZEROCOLOR
				color =  213, 213, 213, 255
			}
		}
	}

Any ideas what I'm doing wrong?

Thanks for your help! :)

Link to comment
Share on other sites

16 hours ago, Angel-125 said:

Any ideas what I'm doing wrong?

The only thing that looks questionable is 'powerOnVariable' - you don't need to include it unless you plan on using a master power switch (and then you'd need to define a master power variable).  Nothing else seems off from a quick inspection.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...