SproutCore--over 20000 lines of new code!

G

Garrett Smith

RobG said:
Jorge said:
(e.g., you don't know
a word of cocoa),
Utterly irrelevant. Apple's Cocoa is a "collection of frameworks, APIs,
and accompanying runtimes"[1] specifically for Mac OS X developers. That
is unrelated to a script library that is supposed to be suitable for web
applications and presumably platforms other than Safari on Mac OS.

In case you didn't know, SproutCore is Cocoa for the Web.

You've been drinking the Kool-Aid.

Jorge posts generally have a very low signal/noise ratio.

That is a line introduced by Apple's
marketing team back in mid-2008 when they announced the new MobileMe
site based on SproutCore. It makes as much sense as calling it .NET for
the web.

".Net for the web" would probably not be good salesmanship for Apple.
The fact that Apple's MobileMe site doesn't even work with their own
mobile devices (iPhone and iPod Touch) gives you some idea of how
accurate marketing terms are.

MobileMe? Isn't that a pay site that allows the user to sign up for
push-notifications of email and syncing photos and stuff?

http://www.apple.com/mobileme/

I think I see.

Does MobileMe use the standard iPhone notifications? Those notifications
interrupt user process to present a modal dialog. Modal dialogs can be
really annoying when trying to do something important, like make a
time-sensitive call. Such modal design actually violates Apples UI
design principles, actually.


Well, iPhone is about hype, and the phone itself, as a phone, is of very
poor quality.

In a way, SproutCore and iPhone match up.
Have a play with the SproutCore site on an iPhone, you'll notice the
following:

- The SproutCore home page takes 20 seconds or longer to load (iPhone
over broadband and WiFi) and throws an error about "ready() is not yet
supported on Safari 3.1 and earlier" as does every page using SproutCore

- The demo page takes over 20 seconds to load

- Going forward and backward between the above two pages takes over 20
seconds so caching appears to work

- You can't scroll to the demos below "user_defaults" (so much for their
cross-platform widgets)

- The bullet images may or may not appear

They're using list-style for mobile? That won't work on a lot of devices.
- Selecting a particular demo is a lottery - the list may or may not
respond to touches

- I have no idea what the iPhone demo is supposed to do, it does nothing

- The user_defaults demo does not work at all, the suggestion text is
cropped by incorrect style settings (it works OK in Firefox)

I could go on. And all that from a demo page for a framework that is
supposed to include mobile devices and specifically target iPhone.

That sounds awful. After looking at the code, I am not surprised that it
has such problems. I've seen places where I can spot exactly how it will
fail (using the `rules` property, using `userAgent` checks). I'm really
surprised that such a large codebase was designed for mobile.
It claims to be "small(ish)" yet is bloated. It claims to do more with
less code (where have we heard that before?) but doesn't. The clock demo
can be written in far less code and be more functional.

Small is a relative term.

Our Sun is much smaller than the anticipated SuperNova Betelgeuse.

Dojo: Small, fast, deep.

Ext:
Ext Core is a cross-browser JavaScript library for building dynamic web
pages. It includes:
* High performance, lightweight

This is called marketing lingo.
SproutCore also embeds most of the styling in the code, so the supposed
abstraction of script and content is completely broken. Have a look at
statements like:
[snip]

That code is a mess. Did anybody at Apple review any of this code before
paying for sponsorship? Or were the reviewees unable to make assessments?

I've seen the demos for the 280 north cappucino (same guys). While the
code is atrocious, they speak and present well.
 
R

RobG

RobG wrote: [...]
That is a line introduced by Apple's
marketing team back in mid-2008 when they announced the new MobileMe
site based on SproutCore. It makes as much sense as calling it .NET for
the web.

".Net for the web" would probably not be good salesmanship for Apple.

Agree. :)

MobileMe? Isn't that a pay site that allows the user to sign up for
push-notifications of email and syncing photos and stuff?

http://www.apple.com/mobileme/

I think I see.

Yes, it is an implementation using SproutCore and an example of the
quality of Apple web sites. They look terrific, but the performance is
sluggish and underneath the technology seems flawed.

Apple seems to have changed the WebObjects foundation of their main
web site and used Prototype.js and scriptaculous.js for browser
functionality. I think playing with SproutCore is an attempt to get
something more integrated, like WO used to be.

Apparently Apple has been working on a new js framework to be bundled
with WebObjects called Gianduia, it seems to be similar to SproutCore
(and also has been called "browser-side Cocoa") so perhaps they are
are still trying to find their web development nirvana.

Does MobileMe use the standard iPhone notifications? Those notifications
interrupt user process to present a modal dialog.

MobileMe is the website that iPhone uses it to synchronise application
data (mail, calendar, bookmarks, etc.) with desktop apps using the
internet (the same functionality is provided by the dock or cable
connector). MobileMe doesn't do large files like iTunes songs or
videos, though other applications like FileMagnet do. Alerts and
dialogs are from the applications and yes, they can be modal and
interrupt other applications. But that is a consequence of the
application design, it is not MobileMe per se.


[...]
Well, iPhone is about hype, and the phone itself, as a phone, is of very
poor quality.

Maybe, but it sure gave the "smart phone" market a kick in the right
direction. :)

In a way, SproutCore and iPhone match up.

Sadly, yes.

Have a play with the SproutCore site on an iPhone, you'll notice the
following: [...]
I could go on. And all that from a demo page for a framework that is
supposed to include mobile devices and specifically target iPhone.

That sounds awful. After looking at the code, I am not surprised that it
has such problems.

To me it is a quality issue. The demos may or may not reflect the
quality of the underlying SproutCore framework, but their shabbiness
is a reflection on the development team's commitment to quality. They
are a terrible advertisement.

I've seen places where I can spot exactly how it will
fail (using the `rules` property, using `userAgent` checks). I'm really
surprised that such a large codebase was designed for mobile.

Yeah, around 600kb minified. Given that the framework includes MVC and
server-side components, I would have expected it to minimise what is
sent to the client and maximise efficiency. It appears to follow the
old Access database idea of shovelling everything off to the client.
It was a bad strategy then for much the same reasons it is a bad
strategy now. A couple of the main ones are that it hogs bandwidth and
is hugely dependent on the client behaving - and browsers are known to
be very badly behaved.

But that seems to be where web applications are headed - instead of
HTML pages with a bit of script to help out, the entire page is
generated by script, with constant AJAX calls in the background to
sync with the server or get more data. It seems like an incredible
waste of resources to me and is utterly dependent on users having
fast, modern machines, one of a limited number of recent browsers (IE
6 is out), and plenty of fast bandwidth.

Many web applications I've developed have had to run in IE 6 over a
64k connection - frameworks like SproutCore are dead in the water.

Small is a relative term.

Yes, but even in "modern" script library terms, 645KB minified is big.
Where "small" really means large, "small(ish)" means enormous.


[...]
I've seen the demos for the 280 north cappucino (same guys). While the
code is atrocious, they speak and present well.

I contacted them about their demos (which were similarly dismal) ages
ago. They didn't seem to think it was an issue. There seems to be
something of a disconnect between the public and web personas, perhaps
that is what raises my hackles.
 
R

Ross Boucher

I contacted them about their demos (which were similarly dismal) ages
ago. They didn't seem to think it was an issue. There seems to be
something of a disconnect between the public and web personas, perhaps
that is what raises my hackles.

Just pointing out this error. Sproutcore and Cappuccino have nothing
to do with each other. Not sure where this "same guys" idea came from.
Also not sure if the rest of these comments are supposed to be about
Cappuccino or about Sproutcore.
 
R

RobG

Just pointing out this error. Sproutcore and Cappuccino have nothing
to do with each other.
OK.

Not sure where this "same guys" idea came from.
Also not sure if the rest of these comments are supposed to be about
Cappuccino or about Sproutcore.

SproutCore. The only comments specifically about Cappuccino are in
that last paragraph.
 
R

Ross Boucher

SproutCore. The only comments specifically about Cappuccino are in
that last paragraph.

About the demos? I can't recall any conversation we might have had,
but I'll agree with you. We haven't been keeping them up to date with
the framework, and we haven't made the time to create more. They are
all on Github, and we've started to collect other projects there as
well, which is a step in the right direction. We're planning a new
community site which will also make it easier to find things.
 
G

Garrett Smith

Ross said:
Just pointing out this error. Sproutcore and Cappuccino have nothing
to do with each other. Not sure where this "same guys" idea came from.

I see.

I believed that both were using Objective-J. Both use some sort of
compiling technology, but Objective-J is used by Cappucino, while
Sproutcore has a different compiling technology. Correct?
Also not sure if the rest of these comments are supposed to be about
Cappuccino or about Sproutcore.
The code being discussed here, in this thread, was Cappucino.

This NG has had code posted from Cappucino before. It has all the same
silly global variables YES, NO, etc.

Thanks for setting the record straight.
 
G

Garrett Smith

Garrett said:
Ross Boucher wrote:

The code being discussed here, in this thread, was Cappucino.

No, Sproutcore was being discussed.

I can't believe I wrote that. And posted it.

The entire thread has been about the subject "SproutCore--over 20000
lines of new code!" and the code samples taken from Sproutcore.

Sorry for the mixup.
 
J

Jorge

There is no need to know about Cocoa at all when reviewing the library
code used by SproutCore, criticisms were based purely on its use of
javascript. If you can show that a specific criticim is not justified
based on some principle of MVC architecture, design pattern, code
style or some other relevant point, please do so.

I'm glad to see that finally, you're beginning to "get it" -albeit
superficially-, "it" being what the library you're criticizing is
about. Because ISTM that a basic -at the very least- understanding of
whatever you're talking about is always a good thing to have before
criticizing. For example, had you known beforehand that sproutcore was
about emulating OSX's Cocoa MVC model and basic framework's
functionality (and no, nothing to do with .NET), you might have
guessed better -given the caliber of the project- that to achieve that
it takes -necessarily- more than a few of lines of JS. Then maybe, as
a second thought, you could have said e.g. that -in your opinion- the
web is not ready for such things yet (I would not agree), instead of
blindly ditching something that you don't even know what is. IOW, you
and the Smith ought to think before you talk.
 
J

Jorge

Lets see. Mr Smith had an error he made pointed out to him and he
acknowledged it. There have been numerous errors and shortcomings in
SproutCore pointed out, but for you the "bad" is still Mr Smith?

Mr. Smith does much more than "an error".
 
R

RobG

I'm glad to see that finally, you're beginning to "get it" -albeit
superficially-, "it" being what the library you're criticizing is
about.

So you think the fact that the title of the thread is drawn from the
SproutCore web site, that specific examples have been drawn from the
site and published demos and that it requires downloading and
installing the framework to inspect the code means we're just making
it all up?

And that someone could do all that and still have no idea what it's
all about?
Because ISTM that a basic -at the very least- understanding of
whatever you're talking about is always a good thing to have before
criticizing. For example, had you known beforehand that sproutcore was
about emulating OSX's Cocoa MVC model and basic framework's
functionality (and no, nothing to do with .NET),

Apparently you haven't understood a single word I've said, and clearly
have no idea that just because SproutCore might be trying to "emulate"
Cocoa, it doesn't make it above criticism of its technical merit.

you might have
guessed better -given the caliber of the project- that to achieve that
it takes -necessarily- more than a few of lines of JS. Then maybe, as
a second thought, you could have said e.g. that -in your opinion- the
web is not ready for such things yet (I would not agree), instead of
blindly ditching something that you don't even know what is. IOW, you
and the Smith ought to think before you talk.

You have been asked several times to show how the criticisms mentioned
here are invalid, yet you haven't posted a single, logical point in
rebuttal. If you think an MVC architecture necessarily requires large
amounts of client-side processing, or the need for large dumps of data
to the client, you haven't explained why you think so despite having
several opportunities.

This discussion is pointless.
 
G

Garrett Smith

Andrew said:
Lets see. Mr Smith had an error he made pointed out to him and he
acknowledged it. There have been numerous errors and shortcomings in
SproutCore pointed out, but for you the "bad" is still Mr Smith?
I did look at the code I reviewed carefully. I did not have time to look
at all of the code. Code review does take time. The code comments I
wrote were fair and should be useful and helpful to the authors. Those
code comments still stand.

The similarities between Sproutcore include influence from Cocoa,
compiling javascript, and variables such as:

var YES = true,
No = false,
etc.

Although Sproutcore and Cappucino have some similarities, they are not
written by the same people.

Late night messages tend to have more typos and bungled edits. For some,
late messages can be more emotional. Me, I tend to be more of a hothead
in the AM, which is why I like to put myself in an environment where
that is suitable (lift heavy weight).

The message in respons to Ross' correction was sent out late, and was
immediately followed by a correction.
 
R

Ross Boucher

The similarities between Sproutcore include influence from Cocoa,
compiling javascript, and variables such as:

var YES = true,
     No = false,
etc.

The YES, NO issue isn't worth much discussion. It is there to make
people coming from a Cocoa background more comfortable. I can't speak
for the Sproutcore team, but Objective-J is a programming language,
and one of the design goals of that language is compatibility with
Objective-C, so there's no reason not to have similar constants. The
arguments against it are stylistic and subjective, but most
importantly it's a completely inconsequential part of both frameworks.
 
G

Garrett Smith

Ross said:
The YES, NO issue isn't worth much discussion.

I think the YES and NO variables are useless. Useless code should be
removed.

It is there to make
people coming from a Cocoa background more comfortable.

Are Cocoa developers finding `true` to be too difficult to understand?

I can't speak
for the Sproutcore team, but Objective-J is a programming language,
and one of the design goals of that language is compatibility with
Objective-C, so there's no reason not to have similar constants. The

I disagree. There are reasons to not have similar constants.

They are a waste of space and reduce efficiency. They take more time to
resolve than a primitive value.

Cocoa developers who are new to javascript will likely have false
expectations, preconceptions, and misconceptions about javascript. The
best way to get rid of those misconceptions is to learn the language.
Providing a layer that makes the javascript look like Cocoa might seem
appealing to Cocoa developers, but it really isn't helping them learn
javascript.

Then again, anyone having trouble understanding `true` and `false` is
probably not worth catering too.
arguments against it are stylistic and subjective, but most
importantly it's a completely inconsequential part of both frameworks.

It is not completely inconsequential. You have added global YES and NO
variables. Every time one of those identifiers is used, it must be
resolved all the way up the scope chain. The value is then obtained and
used in the context where the identifier appears.

In contrast, a boolean primitive `true` will not need to be resolved up
the scope chain. A boolean primitive value will be interpreted immediately.

The result is going to be slower performance for the identifier.

Some implementations may perform tracing and/or upvar optimizations, but
that is not something that is standard or should be expected; you
shouldn't expect anything more than what the specification defines.

Literal `true` should not be confusing for anyone; not even for
non-programmers. `YES` and `NO` are useless.
 
D

David Mark

Thomas said:
David Mark wrote:
We (I think I can speak for all subscribers regarding this) do not need
*such* "code dumps" here, thank you very much.
That is beside the point. Your voice would certainly be heard better and
more clear if you would come to your senses and post something better
readable than this.

Good reviews take time. I can try and take a partial review:

Looking at the datastore:

http://github.com/sproutit/sproutcore/blob/master/frameworks/datastor...

That depends on SC.Object.extend, defined here:-

http://github.com/sproutit/sproutcore/blob/master/frameworks/runtime/...

It is well-commented, I'll give it that.

I'm not accustomed to where everything is defined and don't find it all
right away (the packaging is not intuitive). It is hard to follow method
calls across several files and it is unclear which file the method is
defined in. Things are added to Function.prototype in various places,
but it is uncertain where.

I see global identifiers, such as `YES and `NO` (silly), global
identifiers in IE, via NFE. I see cases not considering older browsers
(hasOwnProperty).

The design of many functions/methods leaks implementation details out
using fake private. This is unnecessary and usually not very hard to avoid.

I also see some benchmarking interspersed with the code. What does
benchmarking have to do with extending objects?

http://github.com/sproutit/sproutcore/blob/master/frameworks/runtime/...

My inline comments as "// (GS) ... ".

extend: function(props) {

// (GS) What does benchmarking have to do with extending objects?
// (GS) I suggest removing the benchmarking. You might want to put it in
// (GS) completely separate AOP layer. Or just get rid of it (I would).
var bench = SC.BENCHMARK_OBJECTS ;
if (bench) SC.Benchmark.start('SC.Object.extend') ;

// build a new constructor and copy class methods. Do this before
// adding any other properties so they are not overwritten by the
// copy.

// (GS) This looks like you're building up a big global SC.Object with
// (GS) more properties coming from anyone who should call
// (GS) `SC.Object.extend`. What is SC.Object defining?
//
// (GS) Why the underscore here? This is a globally-accessible
// (GS) SC.Object.prototype._object_init; it is not really private.
var prop, ret = function(props) { return this._object_init(props);};
for(prop in this) {
if (!this.hasOwnProperty(prop)) continue ;

// (GS) Avoid referencing `this` in static context.
ret[prop] = this[prop];
}

// (GS) `hasOwnProperty` won't work in some implementations.
// (GS) Also, `toString` is not the only problematic one; Did you
// (GS) consider `valueOf`?
// manually copy toString() because some JS engines do not enumerate it

if (this.hasOwnProperty('toString')) ret.toString = this.toString;

// now setup superclass, guid
ret.superclass = this ;
SC.generateGuid(ret); // setup guid

ret.subclasses = SC.Set.create();
this.subclasses.add(ret); // now we can walk a class hierarchy

// setup new prototype and add properties to it
var base = (ret.prototype = SC.beget(this.prototype));
var idx, len = arguments.length;
for(idx=0;idx<len;idx++) SC._object_extend(base, arguments[idx]) ;
base.constructor = ret; // save constructor

// (GS) Again with the benchmarking.
if (bench) SC.Benchmark.end('SC.Object.extend') ;
return ret ;
},

I see that function calls various other functions. I see a call to
SC._object_extend. I've modified the code to wrap at 72 chars.

// (GS) Named FunctionExpression will add a global `_object_extend`
// (GS) property in JScript <= 5.8. I suggest not doing that.
SC._object_extend = function _object_extend(base, ext) {

// (GS) Suggest throwing an object. That helps some Debuggers get a
// (GS) stack trace (error.stack).
if (!ext) throw "SC.Object.extend expects a non-null value. "
+ "Did you forget to 'sc_require' something? Or were you passing a "
+ " Protocol to extend() as if it were a mixin?";

// (GS) There is not need to leak implementation details to the base
// (GS) object. I suggest avoiding doing that, so that these
// (GS) implementation details remain hidden, and can never be relied
// (GS) on.
// set _kvo_cloned for later use
base._kvo_cloned = null;

I've given enough suggestions. There is enough complexity to confuse me.
I managed to find SC.Set.

http://github.com/sproutit/sproutcore/blob/master/frameworks/runtime/...
End.

How's that?

Okay. But isn't this beating a dead horse. Nobody sane would build
widgets (or anything else) on top of an old jQuery version. Browsers
browser documents, documents contain elements, elements contain
attributes. Which of these basic building blocks did Sproutcore get
right? (rhetorical, of course).
 
D

David Mark

It's so funny and ridiculous and seems sooo stupid that the same guys
that advocate turning off JS in the browser (many cljs regulars),

Who "advocates" turning off JS in the browser (and to whom?) Or do
you mean that you want to forget that JS can be turned off so you
don't have to consider the most basic degradation path? Too bad,
Jorge. Welcome to the "Real World".
feel
themselves as an authority so as to judge somebody else's work whose
main goal/underlying idea don't even understand (e.g., you don't know
a word of cocoa), just by looking at a few lines in their JS source.

Cocoa? What does that have to do with any of this? Do you understand
the concept of layers at all? They apply to virtually any kind of
construction. If the foundation is faulty, what will happen to the
building?
 
D

David Mark

Utterly irrelevant. Apple's Cocoa is a "collection of frameworks, APIs,
and accompanying runtimes"[1] specifically for Mac OS X developers. That
is unrelated to a script library that is supposed to be suitable for web
applications and presumably platforms other than Safari on Mac OS.

In case you didn't know, SproutCore is Cocoa for the Web.

In case you didn't know, you are mad. It doesn't matter what beverage
you name it after, the scripts are just browser sniffing compendiums.
In other words, it's the sum total of observations made by incompetent
developers over a period of years (see also, YUI, Closure, jQuery,
etc.) All of the comments are about the state of browsers at the time
the scripts were written. They rarely demosntrate any real
understanding of the issues. Why do you think they need a million
monkeys to "keep up" with three or four browsers?
 
D

David Mark

RobG said:
Jorge said:
(e.g., you don't know
a word of cocoa),
Utterly irrelevant. Apple's Cocoa is a "collection of frameworks, APIs,
and accompanying runtimes"[1] specifically for Mac OS X developers. That
is unrelated to a script library that is supposed to be suitable for web
applications and presumably platforms other than Safari on Mac OS.
In case you didn't know, SproutCore is Cocoa for the Web.
You've been drinking the Kool-Aid.

Jorge posts generally have a very low signal/noise ratio.

That is a line introduced by Apple's
marketing team back in mid-2008 when they announced the new MobileMe
site based on SproutCore. It makes as much sense as calling it .NET for
the web.

".Net for the web" would probably not be good salesmanship for Apple.
The fact that Apple's MobileMe site doesn't even work with their own
mobile devices (iPhone and iPod Touch) gives you some idea of how
accurate marketing terms are.

MobileMe? Isn't that a pay site that allows the user to sign up for
push-notifications of email and syncing photos and stuff?

http://www.apple.com/mobileme/

I think I see.

Does MobileMe use the standard iPhone notifications? Those notifications
interrupt user process to present a modal dialog. Modal dialogs can be
really annoying when trying to do something important, like make a
time-sensitive call. Such modal design actually violates Apples UI
design principles, actually.

Well, iPhone is about hype, and the phone itself, as a phone, is of very
poor quality.

In a way, SproutCore and iPhone match up.


Have a play with the SproutCore site on an iPhone, you'll notice the
following:
- The SproutCore home page takes 20 seconds or longer to load (iPhone
over broadband and WiFi) and throws an error about "ready() is not yet
supported on Safari 3.1 and earlier" as does every page using SproutCore
- The demo page takes over 20 seconds to load
- Going forward and backward between the above two pages takes over 20
seconds so caching appears to work
- You can't scroll to the demos below "user_defaults" (so much for their
cross-platform widgets)
- The bullet images may or may not appear

They're using list-style for mobile? That won't work on a lot of devices.
- Selecting a particular demo is a lottery - the list may or may not
respond to touches
- I have no idea what the iPhone demo is supposed to do, it does nothing
- The user_defaults demo does not work at all, the suggestion text is
cropped by incorrect style settings (it works OK in Firefox)
I could go on. And all that from a demo page for a framework that is
supposed to include mobile devices and specifically target iPhone.

That sounds awful. After looking at the code, I am not surprised that it
has such problems. I've seen places where I can spot exactly how it will
fail (using the `rules` property, using `userAgent` checks). I'm really
surprised that such a large codebase was designed for mobile.
It claims to be "small(ish)" yet is bloated. It claims to do more with
less code (where have we heard that before?) but doesn't. The clock demo
can be written in far less code and be more functional.

Small is a relative term.

Our Sun is much smaller than the anticipated SuperNova Betelgeuse.

Dojo: Small, fast, deep.

That's the funniest thing I've heard all day. :) Large, slow and
shallow would be my summary (and who knows it better?)
Ext:
Ext Core is a cross-browser JavaScript library for building dynamic web
pages. It includes:
* High performance, lightweight

Yeah, bullshit. That one needs a review. I've already looked at the
code and it is another repository for idiotic assumptions based on
cross-eyed observations by incompetent nincompoops.
This is called marketing lingo.

It's called complete bullshit where I come from. The cinsoft.net site
is going to address such deception directly. It's sickening that
businesses are being fed this crap by the barrel.
SproutCore also embeds most of the styling in the code, so the supposed
abstraction of script and content is completely broken. Have a look at
statements like:

[snip]

That code is a mess. Did anybody at Apple review any of this code before
paying for sponsorship? Or were the reviewees unable to make assessments?

Clearly they didn't have a clue. Same for IBM with Dojo and Yahoo
with YUI. The decision-makers are being duped. The developers just
keeping fucking up year after year, no matter how much the major
browsers converge, reinforcing the myth that browser scripting is
impossible (it is for these bums).

I find it amusing that these same bums are now shrieking about
dropping "support" for IE6/7, which they failed to ever figure out.
How do you drop something you don't have (but desperately need)? I'm
referring to understanding, of course (specifically MSHTML).

The Web developers are revolting? Yes, they certainly are.
I've seen the demos for the 280 north cappucino (same guys).

Yes. As I pointed out some time back, it sucks.
While the
code is atrocious, they speak and present well.

I just can't watch twits talk about their latest abominable Website,
library or whatever. Life is too short.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,951
Messages
2,570,113
Members
46,699
Latest member
Abigail89S

Latest Threads

Top