Friday, November 22, 2019

#1 2009-09-14 11:19:37 am

robdut
Member
Registered: 2009-09-02
Posts: 305

user defaults

Hi All,

I am trying to make sense out of the cocoa information on User defaults. If anyone can steer me in the right direction...

Previously I used "Tell User defaults" etc. in ASS apps.

Now in ASOC I am using the bindings for my UI elements so they can be 'set' and "get" simply from script. This is truly great. But I notice you can not bind an element to its property and also to Shared User defaults. I may be wrong.

So what are my options? I thought of using Craigs' booklist example and creating an NSMutableArray object and writing one long record to file, containing all the properties of the UI and also possible another array for a table view...

But I want these user settings to reside in the shared User defaults plist in the user Library Preferences, rather than a separate file somewhere.

Any direction here will help and i will continue research.

Has any one heard about examples coming from apple any time soon? They said 'in a week."

Thanks,
Rob D

Offline

 

#2 2009-09-14 08:33:29 pm

robdut
Member
Registered: 2009-09-02
Posts: 305

Re: user defaults

Ok so I set up a test array and write to file:

Applescript:


property Newarraydata : {{}}
property FILE_PATH : POSIX path of ((path to desktop as string) & "ImageApp.plist")
-- how to get path to bundle resources? "resource path of main bundle no longer works...

--bindings to check boxes
property flipit:0
property rotateit:0
property scaleit:0

Set up the array at launch or read in from file.

Applescript:


on awakeFromNib()
       set Newarraydata to NSMutableArray's alloc()'s initWithContentsOfFile_(FILE_PATH)
       if Newarraydata is equal to missing value then
           set Newarraydata to NSMutableArray's alloc()'s init()
           set arraySettings to {{flipit:flipit, rotateit:rotateit, scaleit:scaleit}}
           Newarraydata's addObjectsFromArray_(arraySettings)
       end if
       my readFile()
   end awakeFromNib

at close:

The file shows the correct values according to the UI checkboxes states after quitting.

on writeToFile()
        (Newarraydata's setValue_forKey_(flipit, "flipit"))
        if not Newarraydata's writeToFile_atomically_(FILE_PATH, true) then
            set messageText to "There was an error writing to file"
            display dialog messageText buttons {"Ok"} default button 1
        end if
    end writeToFile

but then when I read it back in the value is captured for "flipit" but the UI does not update to the new value.

Applescript:


on readFile()
set flipit to Newarraydata's valueForKey_("flipit")
display dialog "" & flipit & "" -- shows correct value but UI doesn't update.
end readFile

Doing it this way though, I still am not using the user defaults plist and have to write out, and read in, every property bound to a Ui element. Just like the old days with "Tell User Defaults..."

Rob D

Offline

 

#3 2009-09-14 08:50:55 pm

robdut
Member
Registered: 2009-09-02
Posts: 305

Re: user defaults

I relaized my error with retrieving the checkbox value:

Applescript:


set thisObject to Newarraydata's objectAtIndex_(0)
setFlipit_(thisObject's valueForKey_("flipit"))

I figured since the array had just one object (containing several key value pairs) I could access the key directly. Not!

But I am still stuck with reading in and out 23 UI properties ( My sample "Newarraydata" has only a few.)

in search of User defaults, Rob

Offline

 

#4 2009-09-15 09:18:34 am

robdut
Member
Registered: 2009-09-02
Posts: 305

Re: user defaults

hi All,
Sorry to answer my own questions...

I found out how to write to user defaults very simply. It isn't really much different from the old "Tell User Defaults" in ASS.

--at the top

Applescript:

property NSUserDefaults : class "NSUserDefaults" of current application

to write to user defaults;

Applescript:

tell NSUserDefaults
   tell its standardUserDefaults()
       its setObject_forKey_(flipit, "flipit")
       its setObject_forKey_(rotateit, "rotateit")
       its setObject_forKey_(scaleit, "scaleit")
   end tell
end tell

to read back in:

Applescript:

tell NSUserDefaults
   tell its standardUserDefaults()
       set flipit to its objectForKey_("flipit")
       my setFlipit_(flipit)
       set rotateit to its objectForKey_("rotateit")
       my setRotateit_(rotateit)
       set scaleit to its objectForKey_("scaleit")
       my setScaleit_(scaleit)
   end tell
end tell

There are more elegant way perhaps...

Applescript:

NSUserDefaults's standardUserDefaults()'s setObject_forKey_(flipit, "flipit")

You can also set the defaults on first run if no defaults exist yet with :

From http://developer.apple.com/mac/library/ … faults.pdf

Applescript:


+ (void)initialize{
}

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary
dictionaryWithObject:@"YES" forKey:@"DeleteBackup"];
[defaults registerDefaults:appDefaults];

getting there slowly. Any feedback or refinements appreciated,

Rob

Offline

 

#5 2009-09-15 05:17:16 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6041

Re: user defaults

One thing to watch out for: you use setObject_forKey_ for text properties, but if the properties are booleans or numbers, you have to use a different method (setBool_forKey_, etc).


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#6 2009-09-15 07:20:41 pm

robdut
Member
Registered: 2009-09-02
Posts: 305

Re: user defaults

Oh - thanks Shane,

I somehow missed that.

just like

"set contents of default entry "flipit" to flipit as boolean."

Same stuff being said as in ASS I guess.

What about storing an array (list of records) in NSUserDefaults?

would setObject_forKey cover that?

I see there are many more getting specifiers than setting ones.

There is an arrayForKey but no setArray_forKey.


Rob

Offline

 

#7 2009-09-15 07:35:15 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6041

Re: user defaults

Yes, setObject_forKey_ works for lists (arrays) and records (dictionaries), but getting them back involves different methods. Best to look up NSUserDefaults in Xcode -> Help -> Developer Documentation.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#8 2009-09-15 07:37:08 pm

robdut
Member
Registered: 2009-09-02
Posts: 305

Re: user defaults

Hi Shane,

I just tried changing objectForKey to boolForKey and setObject_forKey to setBool_forKey but the defaults are not retained. These are for checkboxes which definitely show true and false values and have checkboxes for values in the defaults plist file.

Go figure. objectForKey works for both the booleans and the strings. Just out of curiosity I tried Integer but no go.


Rob

Offline

 

#9 2009-10-04 08:42:38 pm

northridge
Member
Registered: 2009-09-28
Posts: 30

Re: user defaults

Hi all,

I am almost finished my app, and must say it has gone very well after getting through the challenges with my PathControl popups that Shane helped me with in this post :http://macscripter.net/viewtopic.php?id=30644. Surprisingly the app runs smoothly and seems to be bug free. smile  It has 4 user selections and based on user input, I use a repeating NSTimer to  process the user request after it' fires.. includes a countdown timer with updates to the window every second and a log file that annotates all events including user setting changes. Even lets the user change certain settings during the countdown period  on the fly and resets the timer, then restarts the timer . And finaly uses what I learned from Shane's Bindings tutorial to disable the critical controls during processing ! Thanks Shane, I was even able to incorporate a Pause button as an extension of the ideas in that tutorial!

Very pleased with what I've been able to do so far in ASOC, considering I have only coded in AS and never touched AS Studio before beginning this journey.

Now that it is almost ready for prime time all I need to do is save the prefs which are simple in this case.

I now have 2 path controls and 2 popup menus, all of which have null placeholders in them for first run.
Also I have the HFS paths that have been converted from each of the pathcontrols as well as 2 other properties used in the code. Again nothing to be dome on first run.

The problem seems to be saving the pathcontrols using user defaults and being able to read them back to the window after the user selects a new value and quits, then restarts.

I have taken every tutorial available from both the Studio forums, and checked the OBJC stuff out from Apple (which confued me more lol) , and read all the documentation, but nothing seems to be sticking regarding the pathcontrols and the variables, so I am lost on this final part of the app.

This would be a great subject for a complete tutorial using complex controls and their values I think. As I understand it I need not only to restore the controls but also their values which could be 2 different functions?

Could anyone point me in the right direction so I can using applescript coding :
1. set up the default properties internally on first run (Not really needed if I don't set my properties to missing values)
2. save the values for the 4 elements upon user selection using bindings
3. save everything on quit including those pathcontrols (if required, bindings have not worked for me so far on this)
4. get all the values back into my variables/properties on startup including those 2 path controls

Thanks much for any assistance,
Jim

Offline

 

#10 2009-10-04 10:01:19 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6041

Re: user defaults

You should be able to bind the values of the path controls to user defaults, enter suitable keys for them, and leave it at that. That assumes you're no setting their values via bindings already. But it's hard to say any more without seeing what you're actually doing in terms of code and interface.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#11 2009-10-05 08:33:27 pm

northridge
Member
Registered: 2009-09-28
Posts: 30

Re: user defaults

That was it. I was in fact over complicating things. Thank you shane, your answer prompted me to rethink what I was trying to accomplish here lol. The 2 pathControls were bound to user defaults with no issues. The 2 popup buttons' values were previously wired to properties so I just bound them to user defaults and set the properties from the user defaults instance using the read-in methods above. Works perfectly with only one issue left.

I found the old Terminal commands for writing to user defaults and in fact they still work once placed in my script. Testing them I tried to update the code to ASOC code after reading the turorial and class reference, but found robdut's to be the best solution, except of course nothing is happening on launch re: the values from properties I wrote into the user defaults i.e. initializing everything properly on launch, writing first, then reading the file with no values being overwritten,  as explained in the docs.

The way I was doing this with the old terminal commands in Applescript (from tutorials I had taken) was something like this (with variables):
do shell script ("defaults write " & myDomain & " " & (the quoted form of theKey) & " -" & theType & " " & (the quoted form of theValue) as text)   ... and if the property was already there it wasn't changed, and the defaults read command would set everything up for me.  This still works but is very old so I would like to keep as much to ASOC as possible.

I learned that in AS Studio the initialize command was like this:
make new default entry at end of default entries of user defaults with properties {name:"defaultName", contents:"Testing"} from the docs of course    ...but that doesn't work in ASOC.

The code above in this thread for initialization is in OBJC and I would prefer to remain ASOC as much as possible, but just have a hard time constructing (guessing ) the AS version of OBJC, even after the tutorial #5 on the forum for ASOC.

Any idea how to put the tell statement together for the initialize User defaults method in ASOC with 2 internal variables I need to read and write from/to preferences, in my on "applicationWillFinishLaunching" handler?

Property  theFrequency: "100"
Property  theAge: "45"

Many thanks !

Last edited by northridge (2009-10-05 08:47:42 pm)

Offline

 

#12 2009-10-05 09:14:00 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6041

Re: user defaults

If I'm understanding you correctly, you want some way to set the factory defaults that will be used in the absence of defaults saved to a file when the app last ran. If so, you need something like (untested):

Applescript:

       set prefs to {theFrequency:"100", theAge:"45"}
       set userDefaults to current application's class "NSUserDefaults"'s standardUserDefaults()
       userDefaults's registerDefaults_(prefs)

Such prefs are not saved to disk, and are overridden by an app-domain defaults read from disk.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#13 2009-10-06 11:17:02 pm

northridge
Member
Registered: 2009-09-28
Posts: 30

Re: user defaults

Thank you Shane, that worked perfectly. It started the app with the defaults, and when I changed the first value the file was written to the preferences folder. I only used the set, get calls above and the initialization method in your post. As I said above I was overcomplicating things a bit, but using only the 2 properties above let me get my head wrapped around all the automation that bindings and the NSuserdefaults class offers.

My app is done! All in ASOC, and the only non-applescript code was getting the url's from the path controls and this preference code. Just preparing an icon, and it's ready for prime time!

Thanks for your assistance once again.

Offline

 

#14 2009-10-13 07:04:56 am

borhahn
Member
Registered: 2009-10-10
Posts: 3

Re: user defaults

Hi All,

I have a few problems with writing to user defaults:
what do I have to write exactly into the "setObject_forKey_" and the "objectForKey_" parts?

In my application I'm using some text fields and I want to save their values as string.

Example:

property thistextinput_field : missing value     //this is connected to a textfield in the IB

//for working with the value I have this two lines:

set usertext to thistextinput_field's stringValue()
set theusertext to usertext as string

//now the user has to write some text into the text field and after relaunching the application the text should still be in the text field

--> so the question:

What do I have to write in the parts I marked with the questions marks???

//for writing the user defaults

tell NSUserDefaults
   tell its standardUserDefaults()
       its setObject_forKey_(???????, ????????)
   end tell
end tell

//for reading the user defaults

tell NSUserDefaults
   tell its standardUserDefaults()
       set ??????? to its objectForKey_("???????")
       my setFlipit_(flipit) //don't unterstand that line?????????????
   end tell
end tell

Thanks!

Offline

 

#15 2009-10-13 06:28:24 pm

robdut
Member
Registered: 2009-09-02
Posts: 305

Re: user defaults

Hi Borhahn,

You might be better of using capitals to delineate variable names instead of underscores since the mthods use underscores.

so:

set usertext to thistextinput_field's stringValue()

could be

set usertext to thisTextInputFeld's stringValue()

then to read in:

Applescript:

on awakeFromNib()
       tell NSUserDefaults
           tell its standardUserDefaults()
               set thisTextInputFeld to its stringForKey_("thisTextInputFeld")
               my setThisTextInputFeld_(thisTextInputFeld) --this sets your text field's value
           end tell
       end tell
end awakeFromNib

the line

my setThisTextInputFeld_(thisTextInputFeld)

is an accessor method that is built in for your property declared at the top (it simple adds "set" to variable name)

so the "getter" would be

thisTextInputFeld's stringValue()

and the "setter" would be

setThisTextInputFeld_(thisTextInputFeld)  --note the capitalized "This" in your variable name.


then to write out...

Applescript:

on writeToFile()
       tell NSUserDefaults
           tell its standardUserDefaults()
               its setObject_forKey_(thisTextInputFeld, "thisTextInputFeld")
           end tell
       end tell
end writeToFile

You can use the setObject_forKey_ form for writing but should be more specific about reading in with

stringForKey_("thisTextInputFeld")


The defaults use standard key value pairs so you have the value followed by the key

(thisTextInputFeld, "thisTextInputFeld")

you could use different names for the key of course

(thisTextInputFeld, "textFieldKey")

Hope that helps.

Rob

Offline

 

#16 2009-10-14 07:45:44 am

borhahn
Member
Registered: 2009-10-10
Posts: 3

Re: user defaults

Thanks! That helped a lot! smile

Offline

 

#17 2009-11-01 03:48:34 pm

ttt1107
Member
Registered: 2009-08-14
Posts: 63

Re: user defaults

Ok I need help understanding these new defaults. I have a property I want to save which is "thepass" and thepass is set to whatever the user set the password as when he first opened the application. Now I need to save this password and be able to reload the pass on startup next time. I really do not under stand any of the other stuff in this post, could someone show me how this would be written?

Offline

 

#18 2009-11-01 05:05:46 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6041

Re: user defaults

Really, everything you need is in this thread; it's pointless for someone to type it all in again. Re-read -- the code you need is covered in message #4.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#19 2009-11-08 02:50:31 am

genox
Member
Registered: 2009-11-08
Posts: 8

Re: user defaults

Hi,

I'm (very) new to ASOC and currently struggling trying to implement the code described above to work with my application. I did quite some trial-and-error but I just can't get the script to save or read the user defaults. I'm guessing my problem is probably a misconception.. Or I overlooked something. Either way, I would be very glad if someone here could point me into the right direction.

Here's the relevant parts of my script. Everything except for the preferences part works as expected. Basically, there's just 4 text fields containint strings in my app's window which I'd like to include in the preferences file.

My understanding: Load the preferences on initialisation, save the preferences on exit.

Applescript:



script drupdaterAppDelegate
   
   property NSUserDefaults : class "NSUserDefaults" of current application
   
   property statusLogWindow : missing value
   property testServer : missing value
   property modulesOnly : missing value
   property safeUpdate : missing value
   property yftpBookmarkFolder : missing value
   property localDrupalFolder : missing value
   property localBackupFolder : missing value
   property tokenString : missing value
   
   global statusLog, currentDate, curlBrowserString
   
   
   on applicationWillFinishLaunching_(aNotification)
       -- Insert code here to initialize your application before any files are opened        
               
       -- set defaults
       set prefs to {tokenString:"blabla", localBackupFolder:"blablabla"}
       set userDefaults to current application's class "NSUserDefaults"'s standardUserDefaults()
       userDefaults's registerDefaults_(prefs)
       
       -- read prefs
       tell NSUserDefaults
           tell its standardUserDefaults()
               set yftpBookmarkFolder to its objectForKey_("yftpBookmarkFolder")
               my setYftpBookmarkFolder_(yftpBookmarkFolder)
               set localDrupalFolder to its objectForKey_("localDrupalFolder")
               my setLocalDrupalFolder_(localDrupalFolder)
               set localBackupFolder to its objectForKey_("localBackupFolder")
               my setLocalBackupFolder_(localBackupFolder)
               set tokenString to its objectForKey_("tokenString")
               my setTokenString_(tokenString)
           end tell
       end tell
       
   end applicationWillFinishLaunching_

(*

all the other stuff

*)



   on applicationShouldTerminateAfterLastWindowClosed_(sender)
       return true
   end applicationShouldTerminateAfterLastWindowClosed_

   on applicationShouldTerminate_(sender)
       -- Insert code here to do any housekeeping before your application quits
       tell NSUserDefaults
           tell its standardUserDefaults()
               its setObject_forKey_(yftpBookmarkFolder, "yftpBookmarkFolder")
               its setObject_forKey_(localDrupalFolder, "localDrupalFolder")
               its setObject_forKey_(localBackupFolder, "localBackupFolder")
               its setObject_forKey_(tokenString, "tokenString")
           end tell
       end tell
       return my NSTerminateNow
   end applicationShouldTerminate_
   
end script

What am I missing? sad I get the following errors on console:

On initialisation:

08.11.09 09:45:41    drupdater[351]    *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '<NSTextField: 0x20065aa40>' of class 'NSTextField'.
08.11.09 09:45:41    drupdater[351]    *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '<NSTextField: 0x20065ee00>' of class 'NSTextField'.
08.11.09 09:45:41    drupdater[351]    *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '<NSTextField: 0x200659fc0>' of class 'NSTextField'.
08.11.09 09:45:41    drupdater[351]    *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '<NSTextField: 0x200651840>' of class 'NSTextField'.


On exit:

08.11.09 09:46:20    drupdater[351]    [<NSObject 0x7fff70f034a8> valueForUndefinedKey:]: this class is not key value coding-compliant for the key NSTerminateNow.


I'm stuck.. tongue Thanks for any inputs!

Regards,

Oliver

Offline

 

#20 2009-11-08 04:05:16 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6041

Re: user defaults

Could it be that the variables you're trying to save are references to text fields, rather than containing the text in the fields?


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#21 2009-11-08 05:41:16 am

genox
Member
Registered: 2009-11-08
Posts: 8

Re: user defaults

Thanks for the reply!

Yes, in fact I was messing up the syntax and tried to save the text field's reference object instead of the values. It now saves everything as supposed to during applicationShouldTerminate. Thanks for pointing me there.. I probably got a little confused because of the following:

One thing left me puzzled tho and it turns out that this is actually not a bug in my script but rather a bug in ASOC itself: http://lists.apple.com/archives/AppleSc … 00022.html That's why my script failed to save to prefs even tho variables, values and everything was properly assigned. Argh.. tongue

As suggested from the post on Apple's mailing list, I replaced

Applescript:

return my NSTerminateNow

with

Applescript:

return 1

Without this workaround, nothing will be written on closing the application anyways, even if everything's supposed to be working correctly.

(Edit: It's not really a bug in ASOC, it's more like a bug in the ASOC template file xCode provides.)

Last edited by genox (2009-11-08 05:42:43 am)

Offline

 

#22 2009-11-08 05:42:32 am

robdut
Member
Registered: 2009-09-02
Posts: 305

Re: user defaults

genox wrote:

script drupdaterAppDelegate
   
    property NSUserDefaults : class "NSUserDefaults" of current application


This probably isn't causing this problem but the class property should be above the script declaration. You declare

class "NSUserDefaults" of current application

down below though so that should work. Perhaps Shane is right - or are those text fields bound to your variables or connected as outlets?

Rob

Offline

 

#23 2009-11-08 04:35:25 pm

leonsimard
Member
From:: Montreal, Canada
Registered: 2009-09-27
Posts: 531

Re: user defaults

robdut wrote:

You can also set the defaults on first run if no defaults exist yet with :

From http://developer.apple.com/mac/library/ … faults.pdf

Applescript:


+ (void)initialize{
}

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary
dictionaryWithObject:@"YES" forKey:@"DeleteBackup"];
[defaults registerDefaults:appDefaults];

getting there slowly. Any feedback or refinements appreciated,

Rob


Has anyone made this work? I figured out to write some code in ASOC that mimics this ObjC code but it seems not to work:

Applescript:


tell NSUserDefaults
   tell its standardUserDefaults()
       its registerDefaults_(prefQuitIllustrator)
       its registerDefaults_(prefRunFontCacheCleanStartup)
       its registerDefaults_(prefCleanMSOfficeFontCaches)
       its registerDefaults_(theLogDataSource)
   end tell
end tell

Anyone has had any success?

Model: MacBookPro2,2
Browser: Safari 531.9
Operating System: Mac OS X (10.6)

Offline

 

#24 2009-11-08 09:14:58 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6041

Re: user defaults

leonsimard wrote:

Has anyone made this work? I figured out to write some code in ASOC that mimics this ObjC code but it seems not to work:

Applescript:


tell NSUserDefaults
   tell its standardUserDefaults()
       its registerDefaults_(prefQuitIllustrator)
       its registerDefaults_(prefRunFontCacheCleanStartup)
       its registerDefaults_(prefCleanMSOfficeFontCaches)
       its registerDefaults_(theLogDataSource)
   end tell
end tell


You have to pass registerDefaults_ a record -- see the example in message #12 in this topic.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#25 2009-11-08 10:08:53 pm

leonsimard
Member
From:: Montreal, Canada
Registered: 2009-09-27
Posts: 531

Re: user defaults

Really? It only accepts records? Can't set booleans and integers or strings?

Then I guess I would need to read back this record and figure out which one is which and if it can be used to fill an empty variable.

Also, does it mean that it only registers defaults if none was read at startup and will only be saved once we save them at quit time?

Shane Stanley wrote:

Such prefs are not saved to disk, and are overridden by an app-domain defaults read from disk.


Or, it means that we are passing a record of as many properties we need defined as default in one shot to the registerDefaults_(record), and the compiler will know to separate them as properties, using them as default values if none have been read from the plist?

Thanks for the response, i'm starting to get a good hold on ASOC's principles. And sorry if I sound a bit off, it's a bit too late for me to be still awake...

Last edited by leonsimard (2009-11-08 10:14:29 pm)

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)