Feature Proposal: Unifying syntax for addressing specific topic versions


For the background and context, see QueryAcrossTopicRevisions.

A standard "topic address" is of the form Web.Topic.

Currently, where you want a specific revision of a topic, we construct a URL with ?rev=123 or read a macro's documentation to construct Eg.
%FORMFIELD{"Foo" topic="Web.Topic" rev="123"}%


It would be desirable to have an official syntax for addressing web-topic-revisions, for example: you can't de-reference a formfield value of Web.Topic?rev=123 with QuerySearch 's ref operator, Eg.:

  • Currently, GoodTopic may contain Web.Topic but not Web.Topic?rev=123
  • This proposal would support a GoodTopic value of Web.Topic@123, this would retrieve the author of version 123 from Web.Topic

Let's make the Foswiki core support a native topic addressing notation of the form Web.Topic@123.

See also:

Description and Documentation

Therefore, MichaelTempest suggested that we allow the use of @ where PaulHarvey originally suggested -- (as used in PermLinkPlugin) in QueryAcrossTopicRevisions:
  • With wikiwords e.g. Web.TopicName@123
  • In [[bracketed]] links e.g. [[Web.TopicName@123?var=foo#Anchor]]
  • In URLs: e.g. http://example.com/foswiki/bin/Web/TopicName@123
Where a rev=123 URL parameter conflicts with an @234 specifier, let the URL parameter override the latter.



%FORMFIELD{"Foo" topic="Web.Topic" rev="123"}%
%INCLUDE{"Web.Topic" rev="123"}%
%QUERY{"'Web.Topic'/parent.name" rev="123"}% #Doesn't work!


%FORMFIELD{"Foo" topic="Web.Topic@123"}%

Comparison with other wiki platforms

Product Link URL
Foswiki w/PermLinkPlugin
MindTouch (DekiWiki)
{{ web.link(uri.build(Whatever.uri, _, { revision: 123 }), page.title) }}
(form/widget properties)
[[SomeArticle?rev=<'SVN' (nonesequential) id>]]
...SomeArticle?rev=<'SVN' (nonesequential) id>
[$<database GUID>]
[http://www.example.org<scripturl>?oldid=<database GUID>]


Isn't @ an illegal character in a URL?

No (see also: no).

My goal with this proposal is NOT to design a permalink/guid scheme, API, implementation.

But hopefully this proposal can avoid getting in the way of such work and even lay the foundations for it (Eg, by abstracting address paths from ($web, $topic) tuples into Foswiki::Address classes).

Having said that, here are some ideas:
  • Web.Topic@123 - could actually be a stable ID to a web-topic-revision of sorts, even after Web.Topic is renamed - "just" needs a DB of web-topic-rev -> current web-topic. Could be aided by IDs embedded in the topic.txt (Web.Topic@123 had ID 456, resolving it only needs to find where the topic with ID 456 is currently) - actually, we can't distinguish an Web.Topic@123 from an old document that had that name/rev vs a new one that's in its place, so this idea wouldn't work, but a time-based rev (below) could.
  • Web.Topic@2011-05-23T08:03:01+10:00
  • Web.Topic@f81d4fae-7dec-11d0-a765-00a0c91e6bf6
  • ID@f81d4fae-7dec-11d0-a765-00a0c91e6bf6
  • ID:f81d4fae-7dec-11d0-a765-00a0c91e6bf6

@ might not be expressive enough. What about named/parameterised "selectors"?

  • rev=12/Web/Topic
  • Web/Topic(at=2011-04-03)
  • Web/Topic!time=20110502!rev=12
  • We can exted @ if we really want that. Eg.
    • Web/Topic@time=20110502@rev=12
    • Web/Topic@(time=20110502, rev=12)
  • Overlaps with the role of QuerySearch
  • Users already deal with: QuerySearch syntax, WikiText syntax, %MACRO{...}% syntax, HTML... introducing yet another syntax should be avoided
  • These aren't strings a typical user could mentally construct and type out readily (remember: many have trouble linking to topics outside their own web)
  • @ notation has precedence in SVN and Trac products
To compare, MindTouch have a macro-esque syntax for linking with attributes, it looks like:

{{ web.Link("./List.Apply", "Also see List.Apply", "list apply reference") }}




Useful background reading

-- Contributors: MichaelTempest, PaulHarvey, CrawfordCurrie - 09 Dec 2010


Much discussion moved from QueryAcrossTopicRevisions

What we still lack is a canonical identifier for a Web.Topic + particular revision.

What does a result set consisting of only one topic but many of its versions look like?

For what it's worth, the "semantic web"/linked-data world seems to prefer URIs that do away with integer revisions and fully encode a date instead. The returned document contains metadata about which URI to use for next/previous versions.

I personally feel okay with Web.Topic--NNN as PermLinkPlugin does it - but then we have to assume that people don't have topics named this way.

I think Web.Topic--NNN is still less opaque than other systems; I think what you're suggesting is that the alternative should be Web.Topic--YYYYMMDDHHMMSS - the version of a topic that was current for a given time - but then we assume:
  • Things about timezones - users of a given Foswiki system exist across many timezones; one person's timezone may not make much sense to another's
  • That Web.Topic--YYYYMMDDHHMMSS is any less opaque for a user than NNNN don't they just want a handle for a given topic version?

Probably, it would be nice to offer Web.Topic--NNN in a query result, and Web.Topic--YYYYMMDDHHMMSS (and any truncated form) as a shortcut to whatever Web.Topic--NNN was current for the implied time (assumed to be Foswiki's SERVERTIME?)

-- PaulHarvey - 17 Sep 2010

If we're going to use dates (and I don't have a problem with that) then they should be specified according to ISO8601. Date specifiers are not as simple as ID's - two date specifiers may refer to the same revision.

If the intention is to allow revision specifiers in URLs, I am somewhat troubled by the semantics of http://wiki.server/Web/Topic--20100918?rev=54

-- CrawfordCurrie - 18 Sep 2010

http://wiki.server/Web/Topic--20100918T1800 - would be an IOS8601-ish time spec

Maybe we use these rules:
  • If the request contains a ?rev param, don't try to parse the topic name for a --NNN revision part.
  • Only the ending --NNN part of a topic name is recognised as a revision part, ie. --(\w+)$ in regex

http://wiki.server/Web/Topic--20100918?rev=54 - topic 'Topic--20100918' not found

http://wiki.server/Web/Topic--20100918T1800--54 - topic 'Topic--20100918T1800' not found

http://wiki.server/Web/Topic--54--20100918T1800 - topic 'Topic--54' not found

Problem - is Topic--20100918 talking about revision 20100918 or the revision on that date...

Let's use ---YYYYMMDD to imply a date

This approach does require some new macros to make wiki-apping easier. Brainstorming:
  • %NAMEPART{"Web/SubWeb/Topic---20100918" part="revision"}% -> 123 (assuming rev=123 was current on 2010-09-18)
  • %NAMEPART{"Web/SubWeb/Topic---20100918" part="revisiondatetime"}% -> 20100914T172311 (assuming that the rev that was current on 20100918 had modification datetime 20100914T172311)
  • %NAMEPART{"Web/SubWeb/Topic--123" part="revisiondatetime"}% -> 20100914T172311 (assuming rev=123 had datetime 20100914T172311)
  • %NAMEPART{"Web/SubWeb/Topic---20100918" part="revisionepochtime"}% -> 1284484991
  • %NAMEPART{"Web/SubWeb/Topic--123" part="revisionepochtime"}% -> 1284484991
  • %NAMEPART{"Web/SubWeb/Topic--123" part="revision"}% -> 123
  • %NAMEPART{"Web/SubWeb/Topic--123" part="topic"}% -> Topic
  • %NAMEPART{"Web/SubWeb/Topic--123" part="web"}% -> Web/SubWeb
  • %NAMEPART{"Web/SubWeb/Topic--123" part="rootweb"}% -> Web

-- PaulHarvey - 18 Sep 2010

I would appreciate thoughts on the --NNN notation. Maybe @@NNN, @@@YYYYMMDDTHHMMSS is less likely to conflict with real topic names.

-- PaulHarvey - 18 Sep 2010

I don't really like the need to have a different symbol for rev & date, just because it makes the code simpler


I wonder how many times this will need to be typed

and so can't see much need to use up a simple symbol for it.

what I'd propose, is that we define Web.Topic is a shortcut for "Web.Topic[rev='LAST']", and that "Web.Topic[rev='*']" ==
<SvenDowideit> ** Web.Topic implies "Web.Topic[rev='LAST']"
<SvenDowideit> so list of edits _you_ made == "Web.Topic[rev='LAST' && author='You']" ?
<pharvey> +that would be a list of topics whose _last_ author was 'You'
<SvenDowideit> y
<SvenDowideit> s/topics/topic revs of all topics/g
<SvenDowideit> er, no
<SvenDowideit> s/topics/topic revs of Web.Topic/g
<pharvey> +I am very interested in finding a topic that _ever_ had a given author
<pharvey> +but
<SvenDowideit> y, so %SEARCH{"rev="*" && author='Person'"}
<SvenDowideit> what i guess i'm pondering
<SvenDowideit> is that unless you specify rev=... it uses only HEAD
<SvenDowideit> but once you add rev='*' it goes into madness mode
<pharvey> +well the single-topic case is easy I guess.. Web.Topic/revs[author='Person']
<SvenDowideit> ie, in mongodb, it changes from using the head collection, to the history collection
<pharvey> +I don't know how to match more than one topic with query syntax
<pharvey> +name='*'?
<SvenDowideit> or in SQL store, it changes to query the history table
<pharvey> +name='*'/revs[author='Person']
<SvenDowideit> I think web.Topic\revs is un-necessary
<SvenDowideit> nono
<SvenDowideit> treat rev asa property
<SvenDowideit> not as a hash
<SvenDowideit> array
<SvenDowideit> thingy
<SvenDowideit> ie, rev='*' == all revs or all topics
<SvenDowideit>  %SEARCH{"rev="*" && author='Person'"} search for all edits by person, in all topics and all revs

-- SvenDowideit - 27 Sep 2010

I know code speaks louder than talk. But I really am willing to help get this done. I don't need everything implemented all at once, but I strongly believe we need to think about the ecosystem so that the pieces continue to fit together as we progress.

ALERT! I know Crawford said that Foo--123 can't work. Let's pretend that where I use '--' is just a placeholder for some other character/sequence that we haven't discovered yet.

There should be these forms:
  • Topic
  • Web/SubWeb.Topic ('fully qualified topic name')
  • Web/SubWeb.Topic--123 ('fully qualified topic name+rev')

We could do Web/SubWeb.Topic--2010-07-16T19:20:30.45+01:00 too...

It would be a massive boost to user-friendlyness if we had consistency between:
  • URLs, of the form http://translate.foswiki.org/Development/LoadDifferentTopicVersions--123
  • Link syntax, of the form [[Development.LoadDifferentTopicVersions--123]]
  • QUERY syntax, allowing the form

-- PaulHarvey - 08 Dec 2010

I checked in RFC 3986 Uniform Resource Identifier (URI): Generic Syntax - @ is allowed in both the path and the query portion of a URI. I checked in System.TopicsAndWebs#TopicNames (on trunk) and @ is not allowed in topic names.

Therefore, I suggest that we allow the use of @ where Paul has suggested --:
  • With wikiwords e.g. Web.TopicName@123
  • In [[ ]] links e.g. =[[Web.TopicName@123?var=foo#Anchor]]
  • In URLs: e.g. http://example.com/foswiki/bin/Web/TopicName@123

I suggest we specify that a rev=123 URL param overrides @. Also, the revision number should be ignored if the referenced topic does not exist.

If the topic does exist, but the specified revision does not, then pick the current revision and emit a warning.

(Better ideas most welcome smile )

-- MichaelTempest - 09 Dec 2010

How does "emit a warning" work?

I believe a reference to an explicit revision that does not exist should be treated the same way as a reference to a topic that does not exist (and cannot be created) i.e. an error screen. You should not load the latest rev - that's misleading.

-- CrawfordCurrie - 09 Dec 2010

I prefer your error-handling approach.

-- MichaelTempest - 09 Dec 2010

I very much like MichaelTempest 's suggestion of using the @ symbol for revision referencing in all places. It's clean, consistent, and even somewhat human readable. I look at the examples above, and immediately understand what they mean.

I also agree with CrawfordCurrie 's suggested error handling. If you know how to ask for a specific rev, then you clearly want that, and returning anything else would be very misleading, so a hard fail is preferable in this case.

-- AaronFuleki - 16 Dec 2010

In the meantime, the syntax for referencing specific versions in QueryAcrossTopicRevisions has moved on - QUERY syntax now uses versions instead of @. We decided to leave @ for other use in QUERY syntax, so one day @ might mean something completely different in QUERY syntax. Thus, using @ here means inconsistent syntax now, possibly getting worse in the future.

I agree that using @ as described here is clean and readable, but I don't like the inconsistency.

-- MichaelTempest - 17 Dec 2010

I don't really read '@' as being the same as /versions - as long as 'Web.Topic@123'/versions.info.version only returns 123 - it might be workable

-- PaulHarvey - 18 Dec 2010

Something just "feels wrong" with using the @ as a version indicator, as it is also used to recognize e-mail addresses. Will we run into instances where a user has removed @ from the NameFilter and permitted it in topic names? Are there implications with other character sets as more i18n is added to Foswiki? It's not enough to raise a concern, but I somehow suspect that there is a trap in here somewhere.

-- GeorgeClark - 19 Dec 2010

Good point. @ is 7-bit ascii, so my thinking is it can't be more troublesome than any other punctuation... apart from use with email addresses. I guess this is one of those cases where we should send an E-mail to the foswiki-discuss list, to learn if people have relaxed their NameFilter to allow '@' through. We did this when thinking of new TML syntax in SupportBlockquoteAndIndenting too.

-- PaulHarvey - 19 Dec 2010

I've tidied up the proposal, and invited comment from the ML

-- PaulHarvey - 02 May 2011

My 2cent: @ is not intention reveling at all for users, rev=123 is a bit better, best is version ... and almost in line with what we already have in QUERY. So instead of inventing yet another - the third - notation variation (given we have to keep rev for backwards compatibility), we should broaden the sensible choices already made, that is use version=123 as a shortcut for versions[123].

-- MichaelDaum - 02 May 2011

Thanks for the feedback. I'm not entirely clear how the examples would be re-written. Can you give versions[123] equivalent of the #Examples?

Initially when we developed the versions[] syntax in QueryAcrossTopicRevisions, I was trying to keep this stuff ("address notation") consistent with the query syntax, but conflating the two problems didn't seem to be helping.

If we support versions[] in the URL, we might as well support any old QuerySearch expression in the URL. And actually, that would be pretty nifty... is that what you are thinking? It would seem to make "simple" addresses a little expensive to compute & resolve, however (if the address can be any QuerySearch expression).

-- PaulHarvey - 02 May 2011

I'm with SD on questioning how often this would be typed. However if we are going to adopt a shortcut for these constructions, then it should be (1) consistent (2) extensible (3) intuitive. A TML construction such as Web.Topic?version=123 would probably lead users to assume that the full URL parameterisation is available in TML, which it clearly isn't. On the other hand, this syntax would extend nicely to full URL params, should we choose to support that in the future. On balance I think it's probably the cleanest approach.

Note that ?version=123 is absolutely not the same as a query asking for versions[123], as the latter asks for the 123rd revision in the list of revisions i.e. if there are 500 revisions, and revisions are sequentially numbered from 1, it will return the revision numbered 500-123+1 = 376.

  • Outch, so which one is counting backwards, which one forward? And why must one of them be counting backwards? Isn't that inconsistent? -- MichaelDaum - 02 May 2011
  • Neither of them is counting backwards; the versions array in a QUERY is an array of versions indexed most-recent first. The rationale for this is that you do not need to know the size of the array when referring to the latest rev - it is always at index 0. Most-recent-first also allows you to SCALAR the array of versions and end up with the most recent version in your hand, which is important when the result of a versions[] request is used as part of a wider query. It also allows us to support non-sequential revision identifiers, without having nil gaps in the versions array. Note that this is all 1.2/2.0 stuff, so it's not to late to recode it if you have a better solution. -- Crawford
  • Most recent first in the array, that's what I call ordered reverse by date. So rev and versions[] are in reverse logic wrt numbering scheme. That is inconsistent. - Michael.
-- CrawfordCurrie - 02 May 2011

Enhancing all of the url format might make some sense like http://.../Web/Topic!time=20110502!rev=12 (12th revision since 20110502) ... that is not use proper url params for better cacheability and seo friendliness. Another option is to prepend the timestamp to the web.topic like in http://.../time=20110502/rev=12/Web/Topic, or make it even more seo'ed http://.../2011/05/02/12/Web/Topic

-- MichaelDaum - 02 May 2011

There's no reason not to use @ in URLs, so if it's a choice between Web.Topic!rev=123 and Web.Topic@123 then that's an easy choice. Putting the selectors into the URL path is...... horrible. I'd rather use XPath.

-- CrawfordCurrie - 02 May 2011

In any case you'd need a unique URI for a specific version as part of the url scheme as well as for TML. It would be desirable to somewhat be able to derive one from the other without too much of a stretch. As it seems @ is out as Oliver already pointed out on the ML, isn't it.

Still the question is more: why not use a speaking parameter key like time...= and rev...= as in Web.Topic(rev=123) versus a character delimiter like ! or @. What are the pros and cons of both?

-- MichaelDaum - 02 May 2011

As I said on the ML, I have yet to be told a reason why '@' cannot be used in a URL:
  1. The RFCs specifically allow it: read the ABNF for path-absolute in Appendix A of RFC3986, and the guidance to use abs_path (equivalent to 3986 path-absolute) for HTTP URLs in RFC2616:
    3.2.1 General Syntax

    For definitive information on URL syntax and semantics, see "Uniform Resource Identifiers (URI): Generic Syntax and Semantics," RFC 2396 [42] (which replaces RFCs 1738 [4] and RFC 1808 [11]). This specification adopts the definitions of "URI-reference", "absoluteURI", "relativeURI", "port", "host","abs_path", "rel_path", and "authority" from that specification.

    and in case you're interested, the wording on the older RFC2396 reads:
    2.2. Reserved Characters

    The "reserved" syntax class above refers to those characters that are allowed within a URI, but which may not be allowed within a particular component of the generic URI syntax; they are used as delimiters of the components described in Section 3.

    (emphasis mine)
  2. It's up to the HTTP client building the request to comply with RFCs, not Foswiki's HTML output. If "@" were illegal, it would be escaped as %40 automatically.
-- PaulHarvey - 03 May 2011

Michael, excellent point about the "speaking" parameter. And I seem to recall that Deki/MindTouch have some special notation to build "addresses" that can take even more than just a version parameter.

There was some discussion on IRC ages ago about doing a kind of revision-at-datetime notation, but the problem, when I actually thought about how to implement, quickly exploded in several dimensions:
  • Enforce ISO date strings, with TZ offset? You'll note that in my comparison table above, OntoWiki does this
    • But then is it really any easier for an end-user to construct such a date string, than just using the revno? Maybe... (needs UI work!)
  • Or assume server locale TZ if TZ part is missing?
  • What about globally distributed users - maybe we should fix it so topics can set the TZ? Or webs?
  • Supporting non-ISO date strings - is it possible? Desirable? What if the server changes its locale settings, is it okay to break lots of links?
  • Do we give up on all of this and just do a PermLinkPlugin style UID?
-- PaulHarvey - 03 May 2011

My main issue with "speaking" parameters is that they duplicate an existing mechanism in most people's minds. For example,




When do I, a simple, inexperienced, user, use the first, and when do I use the second? And what does



(Of course this applies to other syntaxes such as @123 as well, but the idea of extending to support building more complex addresses sends a shiver up my spine)

On the other hand, the "speaking" parameter approach does lend itself to


rather well. If the bracket syntax is retained specifically for specifying revisions, and revisions only, then I have less of a problem with it.

-- CrawfordCurrie - 03 May 2011

I really like the permalink idea. We should keep that in mind in addition. Permalinks too can have quite different formats used for different reasons:

  • human readable: good seo but might change when the topic or its title changes
  • a unique topic identifier: never ever changes, even after topic name or title changes
The reasons to move parameters to address a specific revision into the URI itself is motivated almost for the same two reasons with the additional more technical consideration of cacheability by browsers and reverse proxies.

Both rev and date are just two different revision labels. They are properties covered and stored by the version control system. Storing any revision label as part of the content itself (some kind of META:REVLABLEL) does not make sense as changing a revlable of one version creates another which is probably not what you want. We suffer from META:TOPICINFO hassles for the same reasons already. That's meta information best stored in the VCS - not the object itself.

As far as I know VCSes allow to store almost any number of labels for an object. So using these in the URI makes a hell of a sense, no matter if it is rev or time or just label. So we are actually quite free to chose whatever we want, but only one at a time of course.

-- MichaelDaum - 03 May 2011

After inviting comment from foswiki-svn and IRC, it seems most of us are happy to go with Web.Topic@123 syntax.

Added criticisms. Added myself and started the clock.

-- PaulHarvey - 21 Sep 2011

For my part, I like the Web.Topic@123 syntax, it seems clear and concise and I think it works well for SVN so there's good precedent supporting it. And the syntax can be extended to support dates Web.Topic@{2011-09-21}

-- BryanThale - 21 Sep 2011

I was wondering what Web.Topic@0 would represent. Presumably the current revision, as would Web.Topic@?

I'm not sure I like this way of disambiguating Web & Topic, but I think the @rev syntax needs to handle the rev=0 and rev='' cases anyway? So would we not get disambiguation for free so to speak? I'm not sure I understand, but the problem stems more from topic vs attachment disambiguation, rather than web In which case why create another syntax to disambiguate Web/Topic? I thought I was recycling an existing syntax - Foswiki supports both '.' and '/' path separators - I agree that making them semantically significant sucks, but I have tried on numerous occasions to get feedback, alternatives are welcome :-)

-- JulianLevens - 04 Jan 2012

The canonical/'normal' form for the address of the latest revision of a topic should be to simply not provide any revision specifier at all.

FWIW trunk's QuerySearch version syntax also uses 0 to refer to the 'latest' version (see QueryAcrossTopicRevisions) - although I had hoped we might be able to change that before releasing this (it seems a bit mad that the index for revision 3 should be -3, but I understand Crawford's desire to avoid the problem that we count revs from 1 whereas perl arrays are 0-indexed).

So should all of the following parse out to exactly the same Foswiki::Address state?
  • Web.Topic
  • Web.Topic@
  • Web.Topic@0

I don't have unit tests asserting this yet.

Whatever we do, MUST be consistent with QuerySearch (and in fact, should be using the same code).

Regarding web & topic disambiguation, replied inline

Please note that the following examples do NOT require any exist-hinting heuristics (they're "normal" form, the parser can figure out the type of thing being addressed without any out-of-band hinting/guessing):

  • Web/
  • Web.Topic
  • Web.Topic/Attachment
  • Web.Topic/Attachment.pdf
  • Web.Topic/Attachment.pdf.zip
  • Web/SubWeb/
  • Web/SubWeb.Topic
  • Web/SubWeb.Topic/Attachment
  • Web/SubWeb.Topic/Attachment.pdf
  • Web/SubWeb.Topic/Attachment.pdf.zip

-- PaulHarvey - 05 Jan 2012

Raising a concern because this seems to have died, and I'm progressing with the versions[] array in queries (which uses a 1-based index)

-- CrawfordCurrie - 24 Feb 2012

Your concern is that this has 'died'? How do I address that, exactly?

Foswiki::Address just is already coded, committed, with unit tests, and I 'just' need to find the time to finish ImplementingLinkProposals

You haven't explained why your versions[] array work conflicts with this, or why even if it does, it should trump the work done for Foswiki::Address - on a proposal which I have had sitting committed for 6 months - which involved extensive consultation and invitation for feedback from foswik-svn, foswiki-discuss, IRC, and twitter.

-- PaulHarvey - 24 Feb 2012

OK, after IRC discussion on the selector for URLs I am happy again, and can lift my concern - which allows the proposal to move into 'Accepted' state. Thanks Paul.

-- CrawfordCurrie - 24 Feb 2012

Thinking further about the %QUERY syntax:

'AnotherWeb.AnotherTopic' is the address of a topic with its complete history whereas 'AnotherWeb.AnotherTopic@4' is the address of a single revision of a topic - which presumably has no versions array. if it has a versions array, then does that array reflect all known versions of the topic (making the @4 redundant) or does it only reflect the versions before [4]?

After discussion on IRC we agreed that making the versions array carry the complete history irrespective of the indexed version is consistent. So 'AnotherWeb.AnotherTopic@4'/versions[5] would refer to version 5 of the topic.

-- CrawfordCurrie - 24 Feb 2012

Changing to Parked. Needs developer to adopt.

b-- Main.GeorgeClark - 19 Nov 2015 - 16:18
Topic revision: r33 - 19 Nov 2015, GeorgeClark
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy