[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Debian JP master SVN www commits (rev.1082)



=======================================================
Repository: /org/svn.debian.or.jp/repos
  Revision: 1082
  Commiter: yasu
      Date: 2010-09-23 20:25:33 +0900 (木, 23  9月 2010)
=======================================================
Log:

add new geoip lib

=======================================================
Changed:

A   cdn/trunk/geoip/
A   cdn/trunk/geoip/.git/
A   cdn/trunk/geoip/.git/HEAD
A   cdn/trunk/geoip/.git/branches/
A   cdn/trunk/geoip/.git/config
A   cdn/trunk/geoip/.git/description
A   cdn/trunk/geoip/.git/hooks/
A   cdn/trunk/geoip/.git/hooks/applypatch-msg.sample
A   cdn/trunk/geoip/.git/hooks/commit-msg.sample
A   cdn/trunk/geoip/.git/hooks/post-commit.sample
A   cdn/trunk/geoip/.git/hooks/post-receive.sample
A   cdn/trunk/geoip/.git/hooks/post-update.sample
A   cdn/trunk/geoip/.git/hooks/pre-applypatch.sample
A   cdn/trunk/geoip/.git/hooks/pre-commit.sample
A   cdn/trunk/geoip/.git/hooks/pre-rebase.sample
A   cdn/trunk/geoip/.git/hooks/prepare-commit-msg.sample
A   cdn/trunk/geoip/.git/hooks/update.sample
A   cdn/trunk/geoip/.git/index
A   cdn/trunk/geoip/.git/info/
A   cdn/trunk/geoip/.git/info/exclude
A   cdn/trunk/geoip/.git/logs/
A   cdn/trunk/geoip/.git/logs/HEAD
A   cdn/trunk/geoip/.git/logs/refs/
A   cdn/trunk/geoip/.git/logs/refs/heads/
A   cdn/trunk/geoip/.git/logs/refs/heads/master
A   cdn/trunk/geoip/.git/objects/
A   cdn/trunk/geoip/.git/objects/info/
A   cdn/trunk/geoip/.git/objects/pack/
A   cdn/trunk/geoip/.git/objects/pack/pack-d66c6f783d4495ac3320b4cca8997c8fa3dc8d29.idx
A   cdn/trunk/geoip/.git/objects/pack/pack-d66c6f783d4495ac3320b4cca8997c8fa3dc8d29.pack
A   cdn/trunk/geoip/.git/packed-refs
A   cdn/trunk/geoip/.git/refs/
A   cdn/trunk/geoip/.git/refs/heads/
A   cdn/trunk/geoip/.git/refs/heads/master
A   cdn/trunk/geoip/.git/refs/remotes/
A   cdn/trunk/geoip/.git/refs/remotes/origin/
A   cdn/trunk/geoip/.git/refs/remotes/origin/HEAD
A   cdn/trunk/geoip/.git/refs/tags/
A   cdn/trunk/geoip/.gitignore
A   cdn/trunk/geoip/History.txt
A   cdn/trunk/geoip/Manifest.txt
A   cdn/trunk/geoip/README.rdoc
A   cdn/trunk/geoip/Rakefile
A   cdn/trunk/geoip/config/
A   cdn/trunk/geoip/config/website.yml
A   cdn/trunk/geoip/geoip.gemspec
A   cdn/trunk/geoip/lib/
A   cdn/trunk/geoip/lib/geoip.rb
A   cdn/trunk/geoip/script/
A   cdn/trunk/geoip/script/destroy
A   cdn/trunk/geoip/script/generate
A   cdn/trunk/geoip/script/txt2html
A   cdn/trunk/geoip/tasks/
A   cdn/trunk/geoip/tasks/website.rake
A   cdn/trunk/geoip/test/
A   cdn/trunk/geoip/test/test_geoip.rb
A   cdn/trunk/geoip/test/test_helper.rb
A   cdn/trunk/geoip/website/
A   cdn/trunk/geoip/website/index.txt
A   cdn/trunk/geoip/website/javascripts/
A   cdn/trunk/geoip/website/javascripts/rounded_corners_lite.inc.js
A   cdn/trunk/geoip/website/stylesheets/
A   cdn/trunk/geoip/website/stylesheets/screen.css
A   cdn/trunk/geoip/website/template.rhtml

Added: cdn/trunk/geoip/.git/HEAD
===================================================================
--- cdn/trunk/geoip/.git/HEAD	                        (rev 0)
+++ cdn/trunk/geoip/.git/HEAD	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1 @@
+ref: refs/heads/master

Added: cdn/trunk/geoip/.git/config
===================================================================
--- cdn/trunk/geoip/.git/config	                        (rev 0)
+++ cdn/trunk/geoip/.git/config	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,11 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = git://github.com/cjheath/geoip.git
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master

Added: cdn/trunk/geoip/.git/description
===================================================================
--- cdn/trunk/geoip/.git/description	                        (rev 0)
+++ cdn/trunk/geoip/.git/description	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.

Added: cdn/trunk/geoip/.git/hooks/applypatch-msg.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/applypatch-msg.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/applypatch-msg.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:

Added: cdn/trunk/geoip/.git/hooks/commit-msg.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/commit-msg.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/commit-msg.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by git-commit with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
+	echo >&2 Duplicate Signed-off-by lines.
+	exit 1
+}

Added: cdn/trunk/geoip/.git/hooks/post-commit.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/post-commit.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/post-commit.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script that is called after a successful
+# commit is made.
+#
+# To enable this hook, rename this file to "post-commit".
+
+: Nothing

Added: cdn/trunk/geoip/.git/hooks/post-receive.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/post-receive.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/post-receive.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script for the "post-receive" event.
+#
+# The "post-receive" script is run after receive-pack has accepted a pack
+# and the repository has been updated.  It is passed arguments in through
+# stdin in the form
+#  <oldrev> <newrev> <refname>
+# For example:
+#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
+#
+# see contrib/hooks/ for a sample, or uncomment the next line and
+# rename the file to "post-receive".
+
+#. /usr/share/doc/git-core/contrib/hooks/post-receive-email

Added: cdn/trunk/geoip/.git/hooks/post-update.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/post-update.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/post-update.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git-update-server-info

Added: cdn/trunk/geoip/.git/hooks/pre-applypatch.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/pre-applypatch.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/pre-applypatch.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:

Added: cdn/trunk/geoip/.git/hooks/pre-commit.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/pre-commit.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/pre-commit.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by git-commit with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git-rev-parse --verify HEAD >/dev/null 2>&1
+then
+	against=HEAD
+else
+	# Initial commit: diff against an empty tree object
+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+	# Note that the use of brackets around a tr range is ok here, (it's
+	# even required, for portability to Solaris 10's /usr/bin/tr), since
+	# the square bracket bytes happen to fall in the designated range.
+	test "$(git diff --cached --name-only --diff-filter=A -z $against |
+	  LC_ALL=C tr -d '[ -~]\0')"
+then
+	echo "Error: Attempt to add a non-ascii file name."
+	echo
+	echo "This can cause problems if you want to work"
+	echo "with people on other platforms."
+	echo
+	echo "To be portable it is advisable to rename the file ..."
+	echo
+	echo "If you know what you are doing you can disable this"
+	echo "check using:"
+	echo
+	echo "  git config hooks.allownonascii true"
+	echo
+	exit 1
+fi
+
+exec git diff-index --check --cached $against --

Added: cdn/trunk/geoip/.git/hooks/pre-rebase.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/pre-rebase.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/pre-rebase.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git-rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD` ||
+	exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+	echo >&2 "No such branch $topic"
+	exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git-rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git-rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
+	perl -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+exit 0
+
+################################################################
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git-rev-list ^master ^topic next
+	git-rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git-rev-list master..topic
+
+	if this is empty, it is fully merged to "master".

Added: cdn/trunk/geoip/.git/hooks/prepare-commit-msg.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/prepare-commit-msg.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/prepare-commit-msg.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by git-commit with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples.  The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+case "$2,$3" in
+  merge,)
+    perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+#   perl -i.bak -pe '
+#      print "\n" . `git diff --cached --name-status -r`
+#	 if /^#/ && $first++ == 0' "$1" ;;
+
+  *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

Added: cdn/trunk/geoip/.git/hooks/update.sample
===================================================================
--- cdn/trunk/geoip/.git/hooks/update.sample	                        (rev 0)
+++ cdn/trunk/geoip/.git/hooks/update.sample	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by git-receive-pack with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+	echo "Don't run this script from the command line." >&2
+	echo " (if you want, you could supply GIT_DIR then run" >&2
+	echo "  $0 <ref> <oldrev> <newrev>)" >&2
+	exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+	exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+	echo "*** Project description file hasn't been set" >&2
+	exit 1
+	;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+	newrev_type=delete
+else
+	newrev_type=$(git-cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+	refs/tags/*,commit)
+		# un-annotated tag
+		short_refname=${refname##refs/tags/}
+		if [ "$allowunannotated" != "true" ]; then
+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,delete)
+		# delete tag
+		if [ "$allowdeletetag" != "true" ]; then
+			echo "*** Deleting a tag is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,tag)
+		# annotated tag
+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+		then
+			echo "*** Tag '$refname' already exists." >&2
+			echo "*** Modifying a tag is not allowed in this repository." >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,commit)
+		# branch
+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+			echo "*** Creating a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,delete)
+		# delete branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/remotes/*,commit)
+		# tracking branch
+		;;
+	refs/remotes/*,delete)
+		# delete tracking branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	*)
+		# Anything else (is there anything else?)
+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+		exit 1
+		;;
+esac
+
+# --- Finished
+exit 0

Added: cdn/trunk/geoip/.git/index
===================================================================
(Binary files differ)


Property changes on: cdn/trunk/geoip/.git/index
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: cdn/trunk/geoip/.git/info/exclude
===================================================================
--- cdn/trunk/geoip/.git/info/exclude	                        (rev 0)
+++ cdn/trunk/geoip/.git/info/exclude	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,6 @@
+# git-ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~

Added: cdn/trunk/geoip/.git/logs/HEAD
===================================================================
--- cdn/trunk/geoip/.git/logs/HEAD	                        (rev 0)
+++ cdn/trunk/geoip/.git/logs/HEAD	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 7d8fc2ac99f766efc30150c9dd854d69584cb992 ARAKI Yasuhiro <araki-y@ay-laptop.(none)> 1282977103 +0900	clone: from git://github.com/cjheath/geoip.git

Added: cdn/trunk/geoip/.git/logs/refs/heads/master
===================================================================
--- cdn/trunk/geoip/.git/logs/refs/heads/master	                        (rev 0)
+++ cdn/trunk/geoip/.git/logs/refs/heads/master	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 7d8fc2ac99f766efc30150c9dd854d69584cb992 ARAKI Yasuhiro <araki-y@ay-laptop.(none)> 1282977103 +0900	clone: from git://github.com/cjheath/geoip.git

Added: cdn/trunk/geoip/.git/objects/pack/pack-d66c6f783d4495ac3320b4cca8997c8fa3dc8d29.idx
===================================================================
(Binary files differ)


Property changes on: cdn/trunk/geoip/.git/objects/pack/pack-d66c6f783d4495ac3320b4cca8997c8fa3dc8d29.idx
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: cdn/trunk/geoip/.git/objects/pack/pack-d66c6f783d4495ac3320b4cca8997c8fa3dc8d29.pack
===================================================================
(Binary files differ)


Property changes on: cdn/trunk/geoip/.git/objects/pack/pack-d66c6f783d4495ac3320b4cca8997c8fa3dc8d29.pack
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: cdn/trunk/geoip/.git/packed-refs
===================================================================
--- cdn/trunk/geoip/.git/packed-refs	                        (rev 0)
+++ cdn/trunk/geoip/.git/packed-refs	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,2 @@
+# pack-refs with: peeled 
+7d8fc2ac99f766efc30150c9dd854d69584cb992 refs/remotes/origin/master

Added: cdn/trunk/geoip/.git/refs/heads/master
===================================================================
--- cdn/trunk/geoip/.git/refs/heads/master	                        (rev 0)
+++ cdn/trunk/geoip/.git/refs/heads/master	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1 @@
+7d8fc2ac99f766efc30150c9dd854d69584cb992

Added: cdn/trunk/geoip/.git/refs/remotes/origin/HEAD
===================================================================
--- cdn/trunk/geoip/.git/refs/remotes/origin/HEAD	                        (rev 0)
+++ cdn/trunk/geoip/.git/refs/remotes/origin/HEAD	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master

Added: cdn/trunk/geoip/.gitignore
===================================================================
--- cdn/trunk/geoip/.gitignore	                        (rev 0)
+++ cdn/trunk/geoip/.gitignore	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,3 @@
+pkg
+website/index.html
+GeoLiteCity.dat

Added: cdn/trunk/geoip/History.txt
===================================================================
--- cdn/trunk/geoip/History.txt	                        (rev 0)
+++ cdn/trunk/geoip/History.txt	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,16 @@
+== 0.8.1 2009-06-04
+
+* Added GeoIP#close method to close the file descriptor
+
+== 0.8.0 2008-08-29
+
+* Added Mutex protection around file I/O for thread safety
+
+== 0.7.0 2008-05-03
+
+* Added Hez Ronningen's patch for using the ISP lookup data file
+
+== 0.5.0 2007-10-24
+
+* 1 major enhancement:
+  * Initial release

Added: cdn/trunk/geoip/Manifest.txt
===================================================================
--- cdn/trunk/geoip/Manifest.txt	                        (rev 0)
+++ cdn/trunk/geoip/Manifest.txt	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,7 @@
+History.txt
+Manifest.txt
+README.rdoc
+Rakefile
+lib/geoip.rb
+test/test_geoip.rb
+test/test_helper.rb

Added: cdn/trunk/geoip/README.rdoc
===================================================================
--- cdn/trunk/geoip/README.rdoc	                        (rev 0)
+++ cdn/trunk/geoip/README.rdoc	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,71 @@
+= geoip
+
+http://github.com/cjheath/geoip
+
+== DESCRIPTION:
+
+GeoIP searches a GeoIP database for a given host or IP address, and
+returns information about the country where the IP address is allocated,
+and the city, ISP and other information, if you have that database version.
+
+== FEATURES/PROBLEMS:
+
+Includes support for ASN data files, thanks to Roland Matiz.
+This release adds support for timezone names, thanks to Tonni Aagesen.
+
+== SYNOPSIS:
+
+  require 'geoip'
+  GeoIP.new('GeoLiteCity.dat').country('www.atlantis.sk')
+  => ["www.atlantis.sk", "217.67.18.26", "SK", "SVK", "Slovakia", "EU", "02", "Bratislava", "", 48.15, 17.1167, nil, nil, "Europe/Bratislava"]
+
+  Returned values are the requested hostname, the IP address as a dotted quad,
+  Maxmind's country code, the ISO3166-1 country code, the ISO3166-2 country code,
+  the ISO3166 country name, and the continent code.
+
+  GeoIP.new('GeoCity.dat').city('github.com')
+  => ["github.com", "207.97.227.239", "US", "USA", "United States", "NA", "CA", "San Francisco", "94110", 37.7484, -122.4156, 807, 415, "America/Los_Angeles"]
+
+  Returned values are the country values followed by region or state name,
+  city name, postal_code/zipcode, latitude, longitude, USA DMA code, USA area code,
+  timezone name. Sorry it's not a Hash... historical.
+
+  GeoIP.new('GeoIPASNum.dat').asn("www.fsb.ru")
+  => ["AS8342", "RTComm.RU Autonomous System"]
+
+== REQUIREMENTS:
+
+You need at least the free GeoLiteCity.dat, for which the last known download
+location is <http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz>,
+or the city database from <http://www.maxmind.com/app/geolitecity>.
+
+The ASN database location is
+<http://geolite.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz>.
+
+This API requires the file to be decompressed for searching. Other versions
+of this database are available for purchase which contain more detailed
+information, but this information is not returned by this implementation.
+See www.maxmind.com for more information.
+
+== INSTALL:
+
+sudo gem install geoip
+
+== LICENSE:
+
+This version Copyright (C) 2005 Clifford Heath
+Derived from the C version, Copyright (C) 2003 MaxMind LLC
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Added: cdn/trunk/geoip/Rakefile
===================================================================
--- cdn/trunk/geoip/Rakefile	                        (rev 0)
+++ cdn/trunk/geoip/Rakefile	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,23 @@
+require 'rubygems'
+gem 'hoe', '>= 2.1.0'
+require 'hoe'
+require 'fileutils'
+require './lib/geoip'
+
+Hoe.plugin :newgem
+Hoe.plugin :website
+
+# Generate all the Rake tasks
+# Run 'rake -T' to see list of generated tasks (from gem root directory)
+$hoe = Hoe.spec 'geoip' do
+  self.developer 'Clifford Heath', 'clifford.heath@xxxxxxxxx'
+  self.developer 'Roland Moriz', 'rmoriz@xxxxxxxxx'
+  self.rubyforge_name       = self.name # TODO this is default value
+end
+
+require 'newgem/tasks'
+Dir['tasks/**/*.rake'].each { |t| load t }
+
+# TODO - want other tests/tasks run by default? Add them to the list
+# remove_task :default
+# task :default => [:spec, :features]

Added: cdn/trunk/geoip/config/website.yml
===================================================================
--- cdn/trunk/geoip/config/website.yml	                        (rev 0)
+++ cdn/trunk/geoip/config/website.yml	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,2 @@
+host: cjheath@xxxxxxxxxxxxx
+remote_dir: /var/www/gforge-projects/geoip

Added: cdn/trunk/geoip/geoip.gemspec
===================================================================
--- cdn/trunk/geoip/geoip.gemspec	                        (rev 0)
+++ cdn/trunk/geoip/geoip.gemspec	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,37 @@
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+  s.name = %q{geoip}
+  s.version = "0.8.5"
+
+  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+  s.authors = ["Clifford Heath", "Roland Moriz"]
+  s.date = %q{2009-09-03}
+  s.description = %q{GeoIP searches a GeoIP database for a given host or IP address, and
+returns information about the country where the IP address is allocated,
+and the city, ISP and other information, if you have that database version.}
+  s.email = ["clifford.heath@xxxxxxxxx", "rmoriz@xxxxxxxxx"]
+  s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
+  s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "lib/geoip.rb", "test/test_geoip.rb", "test/test_helper.rb"]
+  s.has_rdoc = true
+  s.homepage = %q{http://github.com/cjheath/geoip}
+  s.rdoc_options = ["--main", "README.rdoc"]
+  s.require_paths = ["lib"]
+  s.rubyforge_project = %q{geoip}
+  s.rubygems_version = %q{1.3.1}
+  s.summary = %q{GeoIP searches a GeoIP database for a given host or IP address, and returns information about the country where the IP address is allocated, and the city, ISP and other information, if you have that database version.}
+  s.test_files = ["test/test_geoip.rb", "test/test_helper.rb"]
+
+  if s.respond_to? :specification_version then
+    current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+    s.specification_version = 3
+
+    if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
+      s.add_development_dependency(%q<hoe>, [">= 2.3.2"])
+    else
+      s.add_dependency(%q<hoe>, [">= 2.3.2"])
+    end
+  else
+    s.add_dependency(%q<hoe>, [">= 2.3.2"])
+  end
+end

Added: cdn/trunk/geoip/lib/geoip.rb
===================================================================
--- cdn/trunk/geoip/lib/geoip.rb	                        (rev 0)
+++ cdn/trunk/geoip/lib/geoip.rb	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,1028 @@
+$:.unshift File.dirname(__FILE__)
+#
+# Native Ruby reader for the GeoIP database
+# Lookup the country where IP address is allocated
+#
+#= COPYRIGHT
+# This version Copyright (C) 2005 Clifford Heath
+# Derived from the C version, Copyright (C) 2003 MaxMind LLC
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#= SYNOPSIS
+#
+#   require 'geoip'
+#   p GeoIP.new('/usr/share/GeoIP/GeoIP.dat').country("www.netscape.sk")
+#
+#= DESCRIPTION
+#
+# GeoIP searches a GeoIP database for a given host or IP address, and
+# returns information about the country where the IP address is allocated.
+#
+#= PREREQUISITES
+#
+# You need at least the free GeoIP.dat, for which the last known download
+# location is <http://www.maxmind.com/download/geoip/database/GeoIP.dat.gz>
+# This API requires the file to be decompressed for searching. Other versions
+# of this database are available for purchase which contain more detailed
+# information, but this information is not returned by this implementation.
+# See www.maxmind.com for more information.
+#
+#=end
+require 'thread'  # Needed for Mutex
+require 'socket'
+begin
+  require 'io/extra' # for IO.pread
+rescue LoadError
+  # oh well, hope they're not forking after initializing
+end
+
+class GeoIP
+    VERSION = "0.8.7"
+    private
+    CountryCode = [
+        "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN",
+        "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB",
+        "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO",
+        "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD",
+        "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR",
+        "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO",
+        "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ",
+        "FK","FM","FO","FR","FX","GA","GB","GD","GE","GF",
+        "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT",
+        "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID",
+        "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO",
+        "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW",
+        "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT",
+        "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML",
+        "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV",
+        "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI",
+        "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF",
+        "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW",
+        "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD",
+        "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO",
+        "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH",
+        "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW",
+        "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE",
+        "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA",
+        "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE",
+        "BL","MF"
+    ]
+
+    CountryCode3 = [
+        "--","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT",
+        "AGO","AQ","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB",
+        "BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL",
+        "BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC","COD",
+        "CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI",
+        "CUB","CPV","CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM",
+        "DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI",
+        "FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD","GEO","GUF",
+        "GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM",
+        "GUM","GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN",
+        "IRL","ISR","IND","IO","IRQ","IRN","ISL","ITA","JAM","JOR",
+        "JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT",
+        "CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU",
+        "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI",
+        "MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV",
+        "MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC",
+        "NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF",
+        "PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW",
+        "PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN",
+        "SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM",
+        "SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF","TGO","THA",
+        "TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN",
+        "TZA","UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN",
+        "VGB","VIR","VNM","VUT","WLF","WSM","YEM","YT","SRB","ZAF",
+        "ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY",
+        "BLM","MAF"
+    ]
+
+    CountryName = [
+        "N/A",
+        "Asia/Pacific Region",
+        "Europe",
+        "Andorra",
+        "United Arab Emirates",
+        "Afghanistan",
+        "Antigua and Barbuda",
+        "Anguilla",
+        "Albania",
+        "Armenia",
+        "Netherlands Antilles",
+        "Angola",
+        "Antarctica",
+        "Argentina",
+        "American Samoa",
+        "Austria",
+        "Australia",
+        "Aruba",
+        "Azerbaijan",
+        "Bosnia and Herzegovina",
+        "Barbados",
+        "Bangladesh",
+        "Belgium",
+        "Burkina Faso",
+        "Bulgaria",
+        "Bahrain",
+        "Burundi",
+        "Benin",
+        "Bermuda",
+        "Brunei Darussalam",
+        "Bolivia",
+        "Brazil",
+        "Bahamas",
+        "Bhutan",
+        "Bouvet Island",
+        "Botswana",
+        "Belarus",
+        "Belize",
+        "Canada",
+        "Cocos (Keeling) Islands",
+        "Congo, the Democratic Republic of the",
+        "Central African Republic",
+        "Congo",
+        "Switzerland",
+        "Cote D'Ivoire",
+        "Cook Islands",
+        "Chile",
+        "Cameroon",
+        "China",
+        "Colombia",
+        "Costa Rica",
+        "Cuba",
+        "Cape Verde",
+        "Christmas Island",
+        "Cyprus",
+        "Czech Republic",
+        "Germany",
+        "Djibouti",
+        "Denmark",
+        "Dominica",
+        "Dominican Republic",
+        "Algeria",
+        "Ecuador",
+        "Estonia",
+        "Egypt",
+        "Western Sahara",
+        "Eritrea",
+        "Spain",
+        "Ethiopia",
+        "Finland",
+        "Fiji",
+        "Falkland Islands (Malvinas)",
+        "Micronesia, Federated States of",
+        "Faroe Islands",
+        "France",
+        "France, Metropolitan",
+        "Gabon",
+        "United Kingdom",
+        "Grenada",
+        "Georgia",
+        "French Guiana",
+        "Ghana",
+        "Gibraltar",
+        "Greenland",
+        "Gambia",
+        "Guinea",
+        "Guadeloupe",
+        "Equatorial Guinea",
+        "Greece",
+        "South Georgia and the South Sandwich Islands",
+        "Guatemala",
+        "Guam",
+        "Guinea-Bissau",
+        "Guyana",
+        "Hong Kong",
+        "Heard Island and McDonald Islands",
+        "Honduras",
+        "Croatia",
+        "Haiti",
+        "Hungary",
+        "Indonesia",
+        "Ireland",
+        "Israel",
+        "India",
+        "British Indian Ocean Territory",
+        "Iraq",
+        "Iran, Islamic Republic of",
+        "Iceland",
+        "Italy",
+        "Jamaica",
+        "Jordan",
+        "Japan",
+        "Kenya",
+        "Kyrgyzstan",
+        "Cambodia",
+        "Kiribati",
+        "Comoros",
+        "Saint Kitts and Nevis",
+        "Korea, Democratic People's Republic of",
+        "Korea, Republic of",
+        "Kuwait",
+        "Cayman Islands",
+        "Kazakhstan",
+        "Lao People's Democratic Republic",
+        "Lebanon",
+        "Saint Lucia",
+        "Liechtenstein",
+        "Sri Lanka",
+        "Liberia",
+        "Lesotho",
+        "Lithuania",
+        "Luxembourg",
+        "Latvia",
+        "Libyan Arab Jamahiriya",
+        "Morocco",
+        "Monaco",
+        "Moldova, Republic of",
+        "Madagascar",
+        "Marshall Islands",
+        "Macedonia, the Former Yugoslav Republic of",
+        "Mali",
+        "Myanmar",
+        "Mongolia",
+        "Macau",
+        "Northern Mariana Islands",
+        "Martinique",
+        "Mauritania",
+        "Montserrat",
+        "Malta",
+        "Mauritius",
+        "Maldives",
+        "Malawi",
+        "Mexico",
+        "Malaysia",
+        "Mozambique",
+        "Namibia",
+        "New Caledonia",
+        "Niger",
+        "Norfolk Island",
+        "Nigeria",
+        "Nicaragua",
+        "Netherlands",
+        "Norway",
+        "Nepal",
+        "Nauru",
+        "Niue",
+        "New Zealand",
+        "Oman",
+        "Panama",
+        "Peru",
+        "French Polynesia",
+        "Papua New Guinea",
+        "Philippines",
+        "Pakistan",
+        "Poland",
+        "Saint Pierre and Miquelon",
+        "Pitcairn",
+        "Puerto Rico",
+        "Palestinian Territory, Occupied",
+        "Portugal",
+        "Palau",
+        "Paraguay",
+        "Qatar",
+        "Reunion",
+        "Romania",
+        "Russian Federation",
+        "Rwanda",
+        "Saudi Arabia",
+        "Solomon Islands",
+        "Seychelles",
+        "Sudan",
+        "Sweden",
+        "Singapore",
+        "Saint Helena",
+        "Slovenia",
+        "Svalbard and Jan Mayen",
+        "Slovakia",
+        "Sierra Leone",
+        "San Marino",
+        "Senegal",
+        "Somalia",
+        "Suriname",
+        "Sao Tome and Principe",
+        "El Salvador",
+        "Syrian Arab Republic",
+        "Swaziland",
+        "Turks and Caicos Islands",
+        "Chad",
+        "French Southern Territories",
+        "Togo",
+        "Thailand",
+        "Tajikistan",
+        "Tokelau",
+        "Turkmenistan",
+        "Tunisia",
+        "Tonga",
+        "Timor-Leste",
+        "Turkey",
+        "Trinidad and Tobago",
+        "Tuvalu",
+        "Taiwan, Province of China",
+        "Tanzania, United Republic of",
+        "Ukraine",
+        "Uganda",
+        "United States Minor Outlying Islands",
+        "United States",
+        "Uruguay",
+        "Uzbekistan",
+        "Holy See (Vatican City State)",
+        "Saint Vincent and the Grenadines",
+        "Venezuela",
+        "Virgin Islands, British",
+        "Virgin Islands, U.S.",
+        "Viet Nam",
+        "Vanuatu",
+        "Wallis and Futuna",
+        "Samoa",
+        "Yemen",
+        "Mayotte",
+        "Serbia",
+        "South Africa",
+        "Zambia",
+        "Montenegro",
+        "Zimbabwe",
+        "Anonymous Proxy",
+        "Satellite Provider",
+        "Other",
+        "Aland Islands",
+        "Guernsey",
+        "Isle of Man",
+        "Jersey",
+        "Saint Barthelemy",
+        "Saint Martin"
+    ]
+
+    CountryContinent = [
+        "--","AS","EU","EU","AS","AS","SA","SA","EU","AS","SA",
+        "AF","AN","SA","OC","EU","OC","SA","AS","EU","SA",
+        "AS","EU","AF","EU","AS","AF","AF","SA","AS","SA",
+        "SA","SA","AS","AF","AF","EU","SA","NA","AS","AF",
+        "AF","AF","EU","AF","OC","SA","AF","AS","SA","SA",
+        "SA","AF","AS","AS","EU","EU","AF","EU","SA","SA",
+        "AF","SA","EU","AF","AF","AF","EU","AF","EU","OC",
+        "SA","OC","EU","EU","EU","AF","EU","SA","AS","SA",
+        "AF","EU","SA","AF","AF","SA","AF","EU","SA","SA",
+        "OC","AF","SA","AS","AF","SA","EU","SA","EU","AS",
+        "EU","AS","AS","AS","AS","AS","EU","EU","SA","AS",
+        "AS","AF","AS","AS","OC","AF","SA","AS","AS","AS",
+        "SA","AS","AS","AS","SA","EU","AS","AF","AF","EU",
+        "EU","EU","AF","AF","EU","EU","AF","OC","EU","AF",
+        "AS","AS","AS","OC","SA","AF","SA","EU","AF","AS",
+        "AF","NA","AS","AF","AF","OC","AF","OC","AF","SA",
+        "EU","EU","AS","OC","OC","OC","AS","SA","SA","OC",
+        "OC","AS","AS","EU","SA","OC","SA","AS","EU","OC",
+        "SA","AS","AF","EU","AS","AF","AS","OC","AF","AF",
+        "EU","AS","AF","EU","EU","EU","AF","EU","AF","AF",
+        "SA","AF","SA","AS","AF","SA","AF","AF","AF","AS",
+        "AS","OC","AS","AF","OC","AS","AS","SA","OC","AS",
+        "AF","EU","AF","OC","NA","SA","AS","EU","SA","SA",
+        "SA","SA","AS","OC","OC","OC","AS","AF","EU","AF",
+        "AF","EU","AF","--","--","--","EU","EU","EU","EU",
+        "SA","SA"
+    ]
+
+    TimeZone = {
+        "USAL" => "America/Chicago", "USAK" => "America/Anchorage", "USAZ" => "America/Phoenix",
+        "USAR" => "America/Chicago", "USCA" => "America/Los_Angeles", "USCO" => "America/Denver",
+        "USCT" => "America/New_York", "USDE" => "America/New_York", "USDC" => "America/New_York",
+        "USFL" => "America/New_York", "USGA" => "America/New_York", "USHI" => "Pacific/Honolulu",
+        "USID" => "America/Denver", "USIL" => "America/Chicago", "USIN" => "America/Indianapolis",
+        "USIA" => "America/Chicago", "USKS" => "America/Chicago", "USKY" => "America/New_York",
+        "USLA" => "America/Chicago", "USME" => "America/New_York", "USMD" => "America/New_York",
+        "USMA" => "America/New_York", "USMI" => "America/New_York", "USMN" => "America/Chicago",
+        "USMS" => "America/Chicago", "USMO" => "America/Chicago", "USMT" => "America/Denver",
+        "USNE" => "America/Chicago", "USNV" => "America/Los_Angeles", "USNH" => "America/New_York",
+        "USNJ" => "America/New_York", "USNM" => "America/Denver", "USNY" => "America/New_York",
+        "USNC" => "America/New_York", "USND" => "America/Chicago", "USOH" => "America/New_York",
+        "USOK" => "America/Chicago", "USOR" => "America/Los_Angeles", "USPA" => "America/New_York",
+        "USRI" => "America/New_York", "USSC" => "America/New_York", "USSD" => "America/Chicago",
+        "USTN" => "America/Chicago", "USTX" => "America/Chicago", "USUT" => "America/Denver",
+        "USVT" => "America/New_York", "USVA" => "America/New_York", "USWA" => "America/Los_Angeles",
+        "USWV" => "America/New_York", "USWI" => "America/Chicago", "USWY" => "America/Denver",
+        "CAAB" => "America/Edmonton", "CABC" => "America/Vancouver", "CAMB" => "America/Winnipeg",
+        "CANB" => "America/Halifax", "CANL" => "America/St_Johns", "CANT" => "America/Yellowknife",
+        "CANS" => "America/Halifax", "CANU" => "America/Rankin_Inlet", "CAON" => "America/Rainy_River",
+        "CAPE" => "America/Halifax", "CAQC" => "America/Montreal", "CASK" => "America/Regina",
+        "CAYT" => "America/Whitehorse", "AU01" => "Australia/Canberra", "AU02" => "Australia/NSW",
+        "AU03" => "Australia/North", "AU04" => "Australia/Queensland", "AU05" => "Australia/South",
+        "AU06" => "Australia/Tasmania", "AU07" => "Australia/Victoria", "AU08" => "Australia/West",
+        "AS" => "US/Samoa", "CI" => "Africa/Abidjan", "GH" => "Africa/Accra",
+        "DZ" => "Africa/Algiers", "ER" => "Africa/Asmera", "ML" => "Africa/Bamako",
+        "CF" => "Africa/Bangui", "GM" => "Africa/Banjul", "GW" => "Africa/Bissau",
+        "CG" => "Africa/Brazzaville", "BI" => "Africa/Bujumbura", "EG" => "Africa/Cairo",
+        "MA" => "Africa/Casablanca", "GN" => "Africa/Conakry", "SN" => "Africa/Dakar",
+        "DJ" => "Africa/Djibouti", "SL" => "Africa/Freetown", "BW" => "Africa/Gaborone",
+        "ZW" => "Africa/Harare", "ZA" => "Africa/Johannesburg", "UG" => "Africa/Kampala",
+        "SD" => "Africa/Khartoum", "RW" => "Africa/Kigali", "NG" => "Africa/Lagos",
+        "GA" => "Africa/Libreville", "TG" => "Africa/Lome", "AO" => "Africa/Luanda",
+        "ZM" => "Africa/Lusaka", "GQ" => "Africa/Malabo", "MZ" => "Africa/Maputo",
+        "LS" => "Africa/Maseru", "SZ" => "Africa/Mbabane", "SO" => "Africa/Mogadishu",
+        "LR" => "Africa/Monrovia", "KE" => "Africa/Nairobi", "TD" => "Africa/Ndjamena",
+        "NE" => "Africa/Niamey", "MR" => "Africa/Nouakchott", "BF" => "Africa/Ouagadougou",
+        "ST" => "Africa/Sao_Tome", "LY" => "Africa/Tripoli", "TN" => "Africa/Tunis",
+        "AI" => "America/Anguilla", "AG" => "America/Antigua", "AW" => "America/Aruba",
+        "BB" => "America/Barbados", "BZ" => "America/Belize", "CO" => "America/Bogota",
+        "VE" => "America/Caracas", "KY" => "America/Cayman", "CR" => "America/Costa_Rica",
+        "DM" => "America/Dominica", "SV" => "America/El_Salvador", "GD" => "America/Grenada",
+        "FR" => "Europe/Paris", "GP" => "America/Guadeloupe", "GT" => "America/Guatemala",
+        "GY" => "America/Guyana", "CU" => "America/Havana", "JM" => "America/Jamaica",
+        "BO" => "America/La_Paz", "PE" => "America/Lima", "NI" => "America/Managua",
+        "MQ" => "America/Martinique", "UY" => "America/Montevideo", "MS" => "America/Montserrat",
+        "BS" => "America/Nassau", "PA" => "America/Panama", "SR" => "America/Paramaribo",
+        "PR" => "America/Puerto_Rico", "KN" => "America/St_Kitts", "LC" => "America/St_Lucia",
+        "VC" => "America/St_Vincent", "HN" => "America/Tegucigalpa", "YE" => "Asia/Aden",
+        "JO" => "Asia/Amman", "TM" => "Asia/Ashgabat", "IQ" => "Asia/Baghdad",
+        "BH" => "Asia/Bahrain", "AZ" => "Asia/Baku", "TH" => "Asia/Bangkok",
+        "LB" => "Asia/Beirut", "KG" => "Asia/Bishkek", "BN" => "Asia/Brunei",
+        "IN" => "Asia/Calcutta", "MN" => "Asia/Choibalsan", "LK" => "Asia/Colombo",
+        "BD" => "Asia/Dhaka", "AE" => "Asia/Dubai", "TJ" => "Asia/Dushanbe",
+        "HK" => "Asia/Hong_Kong", "TR" => "Asia/Istanbul", "IL" => "Asia/Jerusalem",
+        "AF" => "Asia/Kabul", "PK" => "Asia/Karachi", "NP" => "Asia/Katmandu",
+        "KW" => "Asia/Kuwait", "MO" => "Asia/Macao", "PH" => "Asia/Manila",
+        "OM" => "Asia/Muscat", "CY" => "Asia/Nicosia", "KP" => "Asia/Pyongyang",
+        "QA" => "Asia/Qatar", "MM" => "Asia/Rangoon", "SA" => "Asia/Riyadh",
+        "KR" => "Asia/Seoul", "SG" => "Asia/Singapore", "TW" => "Asia/Taipei",
+        "GE" => "Asia/Tbilisi", "BT" => "Asia/Thimphu", "JP" => "Asia/Tokyo",
+        "LA" => "Asia/Vientiane", "AM" => "Asia/Yerevan", "BM" => "Atlantic/Bermuda",
+        "CV" => "Atlantic/Cape_Verde", "FO" => "Atlantic/Faeroe", "IS" => "Atlantic/Reykjavik",
+        "GS" => "Atlantic/South_Georgia", "SH" => "Atlantic/St_Helena", "CL" => "Chile/Continental",
+        "NL" => "Europe/Amsterdam", "AD" => "Europe/Andorra", "GR" => "Europe/Athens",
+        "YU" => "Europe/Belgrade", "DE" => "Europe/Berlin", "SK" => "Europe/Bratislava",
+        "BE" => "Europe/Brussels", "RO" => "Europe/Bucharest", "HU" => "Europe/Budapest",
+        "DK" => "Europe/Copenhagen", "IE" => "Europe/Dublin", "GI" => "Europe/Gibraltar",
+        "FI" => "Europe/Helsinki", "SI" => "Europe/Ljubljana", "GB" => "Europe/London",
+        "LU" => "Europe/Luxembourg", "MT" => "Europe/Malta", "BY" => "Europe/Minsk",
+        "MC" => "Europe/Monaco", "NO" => "Europe/Oslo", "CZ" => "Europe/Prague",
+        "LV" => "Europe/Riga", "IT" => "Europe/Rome", "SM" => "Europe/San_Marino",
+        "BA" => "Europe/Sarajevo", "MK" => "Europe/Skopje", "BG" => "Europe/Sofia",
+        "SE" => "Europe/Stockholm", "EE" => "Europe/Tallinn", "AL" => "Europe/Tirane",
+        "LI" => "Europe/Vaduz", "VA" => "Europe/Vatican", "AT" => "Europe/Vienna",
+        "LT" => "Europe/Vilnius", "PL" => "Europe/Warsaw", "HR" => "Europe/Zagreb",
+        "IR" => "Asia/Tehran", "MG" => "Indian/Antananarivo", "CX" => "Indian/Christmas",
+        "CC" => "Indian/Cocos", "KM" => "Indian/Comoro", "MV" => "Indian/Maldives",
+        "MU" => "Indian/Mauritius", "YT" => "Indian/Mayotte", "RE" => "Indian/Reunion",
+        "FJ" => "Pacific/Fiji", "TV" => "Pacific/Funafuti", "GU" => "Pacific/Guam",
+        "NR" => "Pacific/Nauru", "NU" => "Pacific/Niue", "NF" => "Pacific/Norfolk",
+        "PW" => "Pacific/Palau", "PN" => "Pacific/Pitcairn", "CK" => "Pacific/Rarotonga",
+        "WS" => "Pacific/Samoa", "KI" => "Pacific/Tarawa", "TO" => "Pacific/Tongatapu",
+        "WF" => "Pacific/Wallis", "TZ" => "Africa/Dar_es_Salaam", "VN" => "Asia/Phnom_Penh",
+        "KH" => "Asia/Phnom_Penh", "CM" => "Africa/Lagos", "DO" => "America/Santo_Domingo",
+        "ET" => "Africa/Addis_Ababa", "FX" => "Europe/Paris", "HT" => "America/Port-au-Prince",
+        "CH" => "Europe/Zurich", "AN" => "America/Curacao", "BJ" => "Africa/Porto-Novo",
+        "EH" => "Africa/El_Aaiun", "FK" => "Atlantic/Stanley", "GF" => "America/Cayenne",
+        "IO" => "Indian/Chagos", "MD" => "Europe/Chisinau", "MP" => "Pacific/Saipan",
+        "MW" => "Africa/Blantyre", "NA" => "Africa/Windhoek", "NC" => "Pacific/Noumea",
+        "PG" => "Pacific/Port_Moresby", "PM" => "America/Miquelon", "PS" => "Asia/Gaza",
+        "PY" => "America/Asuncion", "SB" => "Pacific/Guadalcanal", "SC" => "Indian/Mahe",
+        "SJ" => "Arctic/Longyearbyen", "SY" => "Asia/Damascus", "TC" => "America/Grand_Turk",
+        "TF" => "Indian/Kerguelen", "TK" => "Pacific/Fakaofo", "TT" => "America/Port_of_Spain",
+        "VG" => "America/Tortola", "VI" => "America/St_Thomas", "VU" => "Pacific/Efate",
+        "RS" => "Europe/Belgrade", "ME" => "Europe/Podgorica", "AX" => "Europe/Mariehamn",
+        "GG" => "Europe/Guernsey", "IM" => "Europe/Isle_of_Man", "JE" => "Europe/Jersey",
+        "BL" => "America/St_Barthelemy", "MF" => "America/Marigot", "AR01" => "America/Argentina/Buenos_Aires",
+        "AR02" => "America/Argentina/Catamarca", "AR03" => "America/Argentina/Tucuman", "AR04" => "America/Argentina/Rio_Gallegos",
+        "AR05" => "America/Argentina/Cordoba", "AR06" => "America/Argentina/Tucuman", "AR07" => "America/Argentina/Buenos_Aires",
+        "AR08" => "America/Argentina/Buenos_Aires", "AR09" => "America/Argentina/Tucuman", "AR10" => "America/Argentina/Jujuy",
+        "AR11" => "America/Argentina/San_Luis", "AR12" => "America/Argentina/La_Rioja", "AR13" => "America/Argentina/Mendoza",
+        "AR14" => "America/Argentina/Buenos_Aires", "AR15" => "America/Argentina/San_Luis", "AR16" => "America/Argentina/Buenos_Aires",
+        "AR17" => "America/Argentina/Salta", "AR18" => "America/Argentina/San_Juan", "AR19" => "America/Argentina/San_Luis",
+        "AR20" => "America/Argentina/Rio_Gallegos", "AR21" => "America/Argentina/Buenos_Aires", "AR22" => "America/Argentina/Catamarca",
+        "AR23" => "America/Argentina/Ushuaia", "AR24" => "America/Argentina/Tucuman", "BR01" => "America/Rio_Branco",
+        "BR02" => "America/Maceio", "BR03" => "America/Sao_Paulo", "BR04" => "America/Manaus",
+        "BR05" => "America/Bahia", "BR06" => "America/Fortaleza", "BR07" => "America/Sao_Paulo",
+        "BR08" => "America/Sao_Paulo", "BR11" => "America/Campo_Grande", "BR13" => "America/Belem",
+        "BR14" => "America/Cuiaba", "BR15" => "America/Sao_Paulo", "BR16" => "America/Belem",
+        "BR17" => "America/Recife", "BR18" => "America/Sao_Paulo", "BR20" => "America/Fortaleza",
+        "BR21" => "America/Sao_Paulo", "BR22" => "America/Recife", "BR23" => "America/Sao_Paulo",
+        "BR24" => "America/Porto_Velho", "BR25" => "America/Boa_Vista", "BR26" => "America/Sao_Paulo",
+        "BR27" => "America/Sao_Paulo", "BR28" => "America/Maceio", "BR29" => "America/Sao_Paulo",
+        "BR30" => "America/Recife", "BR31" => "America/Araguaina", "CD02" => "Africa/Kinshasa",
+        "CD05" => "Africa/Lubumbashi", "CD06" => "Africa/Kinshasa", "CD08" => "Africa/Kinshasa",
+        "CD10" => "Africa/Lubumbashi", "CD11" => "Africa/Lubumbashi", "CD12" => "Africa/Lubumbashi",
+        "CN01" => "Asia/Shanghai", "CN02" => "Asia/Shanghai", "CN03" => "Asia/Shanghai",
+        "CN04" => "Asia/Shanghai", "CN05" => "Asia/Harbin", "CN06" => "Asia/Chongqing",
+        "CN07" => "Asia/Shanghai", "CN08" => "Asia/Harbin", "CN09" => "Asia/Shanghai",
+        "CN10" => "Asia/Shanghai", "CN11" => "Asia/Chongqing", "CN12" => "Asia/Shanghai",
+        "CN13" => "Asia/Urumqi", "CN14" => "Asia/Chongqing", "CN15" => "Asia/Chongqing",
+        "CN16" => "Asia/Chongqing", "CN18" => "Asia/Chongqing", "CN19" => "Asia/Harbin",
+        "CN20" => "Asia/Harbin", "CN21" => "Asia/Chongqing", "CN22" => "Asia/Harbin",
+        "CN23" => "Asia/Shanghai", "CN24" => "Asia/Chongqing", "CN25" => "Asia/Shanghai",
+        "CN26" => "Asia/Chongqing", "CN28" => "Asia/Shanghai", "CN29" => "Asia/Chongqing",
+        "CN30" => "Asia/Chongqing", "CN31" => "Asia/Chongqing", "CN32" => "Asia/Chongqing",
+        "CN33" => "Asia/Chongqing", "EC01" => "Pacific/Galapagos", "EC02" => "America/Guayaquil",
+        "EC03" => "America/Guayaquil", "EC04" => "America/Guayaquil", "EC05" => "America/Guayaquil",
+        "EC06" => "America/Guayaquil", "EC07" => "America/Guayaquil", "EC08" => "America/Guayaquil",
+        "EC09" => "America/Guayaquil", "EC10" => "America/Guayaquil", "EC11" => "America/Guayaquil",
+        "EC12" => "America/Guayaquil", "EC13" => "America/Guayaquil", "EC14" => "America/Guayaquil",
+        "EC15" => "America/Guayaquil", "EC17" => "America/Guayaquil", "EC18" => "America/Guayaquil",
+        "EC19" => "America/Guayaquil", "EC20" => "America/Guayaquil", "EC22" => "America/Guayaquil",
+        "ES07" => "Europe/Madrid", "ES27" => "Europe/Madrid", "ES29" => "Europe/Madrid",
+        "ES31" => "Europe/Madrid", "ES32" => "Europe/Madrid", "ES34" => "Europe/Madrid",
+        "ES39" => "Europe/Madrid", "ES51" => "Africa/Ceuta", "ES52" => "Europe/Madrid",
+        "ES53" => "Atlantic/Canary", "ES54" => "Europe/Madrid", "ES55" => "Europe/Madrid",
+        "ES56" => "Europe/Madrid", "ES57" => "Europe/Madrid", "ES58" => "Europe/Madrid",
+        "ES59" => "Europe/Madrid", "ES60" => "Europe/Madrid", "GL01" => "America/Thule",
+        "GL02" => "America/Godthab", "GL03" => "America/Godthab", "ID01" => "Asia/Pontianak",
+        "ID02" => "Asia/Makassar", "ID03" => "Asia/Jakarta", "ID04" => "Asia/Jakarta",
+        "ID05" => "Asia/Jakarta", "ID06" => "Asia/Jakarta", "ID07" => "Asia/Jakarta",
+        "ID08" => "Asia/Jakarta", "ID09" => "Asia/Jayapura", "ID10" => "Asia/Jakarta",
+        "ID11" => "Asia/Pontianak", "ID12" => "Asia/Makassar", "ID13" => "Asia/Makassar",
+        "ID14" => "Asia/Makassar", "ID15" => "Asia/Jakarta", "ID16" => "Asia/Makassar",
+        "ID17" => "Asia/Makassar", "ID18" => "Asia/Makassar", "ID19" => "Asia/Pontianak",
+        "ID20" => "Asia/Makassar", "ID21" => "Asia/Makassar", "ID22" => "Asia/Makassar",
+        "ID23" => "Asia/Makassar", "ID24" => "Asia/Jakarta", "ID25" => "Asia/Pontianak",
+        "ID26" => "Asia/Pontianak", "ID30" => "Asia/Jakarta", "ID31" => "Asia/Makassar",
+        "ID33" => "Asia/Jakarta", "KZ01" => "Asia/Almaty", "KZ02" => "Asia/Almaty",
+        "KZ03" => "Asia/Qyzylorda", "KZ04" => "Asia/Aqtobe", "KZ05" => "Asia/Qyzylorda",
+        "KZ06" => "Asia/Aqtau", "KZ07" => "Asia/Oral", "KZ08" => "Asia/Qyzylorda",
+        "KZ09" => "Asia/Aqtau", "KZ10" => "Asia/Qyzylorda", "KZ11" => "Asia/Almaty",
+        "KZ12" => "Asia/Qyzylorda", "KZ13" => "Asia/Aqtobe", "KZ14" => "Asia/Qyzylorda",
+        "KZ15" => "Asia/Almaty", "KZ16" => "Asia/Aqtobe", "KZ17" => "Asia/Almaty",
+        "MX01" => "America/Mexico_City", "MX02" => "America/Tijuana", "MX03" => "America/Hermosillo",
+        "MX04" => "America/Merida", "MX05" => "America/Mexico_City", "MX06" => "America/Chihuahua",
+        "MX07" => "America/Monterrey", "MX08" => "America/Mexico_City", "MX09" => "America/Mexico_City",
+        "MX10" => "America/Mazatlan", "MX11" => "America/Mexico_City", "MX12" => "America/Mexico_City",
+        "MX13" => "America/Mexico_City", "MX14" => "America/Mazatlan", "MX15" => "America/Chihuahua",
+        "MX16" => "America/Mexico_City", "MX17" => "America/Mexico_City", "MX18" => "America/Mazatlan",
+        "MX19" => "America/Monterrey", "MX20" => "America/Mexico_City", "MX21" => "America/Mexico_City",
+        "MX22" => "America/Mexico_City", "MX23" => "America/Cancun", "MX24" => "America/Mexico_City",
+        "MX25" => "America/Mazatlan", "MX26" => "America/Hermosillo", "MX27" => "America/Merida",
+        "MX28" => "America/Monterrey", "MX29" => "America/Mexico_City", "MX30" => "America/Mexico_City",
+        "MX31" => "America/Merida", "MX32" => "America/Monterrey", "MY01" => "Asia/Kuala_Lumpur",
+        "MY02" => "Asia/Kuala_Lumpur", "MY03" => "Asia/Kuala_Lumpur", "MY04" => "Asia/Kuala_Lumpur",
+        "MY05" => "Asia/Kuala_Lumpur", "MY06" => "Asia/Kuala_Lumpur", "MY07" => "Asia/Kuala_Lumpur",
+        "MY08" => "Asia/Kuala_Lumpur", "MY09" => "Asia/Kuala_Lumpur", "MY11" => "Asia/Kuching",
+        "MY12" => "Asia/Kuala_Lumpur", "MY13" => "Asia/Kuala_Lumpur", "MY14" => "Asia/Kuala_Lumpur",
+        "MY15" => "Asia/Kuching", "MY16" => "Asia/Kuching", "NZ85" => "Pacific/Auckland",
+        "NZE7" => "Pacific/Auckland", "NZE8" => "Pacific/Auckland", "NZE9" => "Pacific/Auckland",
+        "NZF1" => "Pacific/Auckland", "NZF2" => "Pacific/Auckland", "NZF3" => "Pacific/Auckland",
+        "NZF4" => "Pacific/Auckland", "NZF5" => "Pacific/Auckland", "NZF7" => "Pacific/Chatham",
+        "NZF8" => "Pacific/Auckland", "NZF9" => "Pacific/Auckland", "NZG1" => "Pacific/Auckland",
+        "NZG2" => "Pacific/Auckland", "NZG3" => "Pacific/Auckland", "PT02" => "Europe/Lisbon",
+        "PT03" => "Europe/Lisbon", "PT04" => "Europe/Lisbon", "PT05" => "Europe/Lisbon",
+        "PT06" => "Europe/Lisbon", "PT07" => "Europe/Lisbon", "PT08" => "Europe/Lisbon",
+        "PT09" => "Europe/Lisbon", "PT10" => "Atlantic/Madeira", "PT11" => "Europe/Lisbon",
+        "PT13" => "Europe/Lisbon", "PT14" => "Europe/Lisbon", "PT16" => "Europe/Lisbon",
+        "PT17" => "Europe/Lisbon", "PT18" => "Europe/Lisbon", "PT19" => "Europe/Lisbon",
+        "PT20" => "Europe/Lisbon", "PT21" => "Europe/Lisbon", "PT22" => "Europe/Lisbon",
+        "RU01" => "Europe/Volgograd", "RU02" => "Asia/Irkutsk", "RU03" => "Asia/Novokuznetsk",
+        "RU04" => "Asia/Novosibirsk", "RU05" => "Asia/Vladivostok", "RU06" => "Europe/Moscow",
+        "RU07" => "Europe/Volgograd", "RU08" => "Europe/Samara", "RU09" => "Europe/Moscow",
+        "RU10" => "Europe/Moscow", "RU11" => "Asia/Irkutsk", "RU13" => "Asia/Yekaterinburg",
+        "RU14" => "Asia/Irkutsk", "RU15" => "Asia/Anadyr", "RU16" => "Europe/Samara",
+        "RU17" => "Europe/Volgograd", "RU18" => "Asia/Krasnoyarsk", "RU20" => "Asia/Irkutsk",
+        "RU21" => "Europe/Moscow", "RU22" => "Europe/Volgograd", "RU23" => "Europe/Kaliningrad",
+        "RU24" => "Europe/Volgograd", "RU25" => "Europe/Moscow", "RU26" => "Asia/Kamchatka",
+        "RU27" => "Europe/Volgograd", "RU28" => "Europe/Moscow", "RU29" => "Asia/Novokuznetsk",
+        "RU30" => "Asia/Vladivostok", "RU31" => "Asia/Krasnoyarsk", "RU32" => "Asia/Omsk",
+        "RU33" => "Asia/Yekaterinburg", "RU34" => "Asia/Yekaterinburg", "RU35" => "Asia/Yekaterinburg",
+        "RU36" => "Asia/Anadyr", "RU37" => "Europe/Moscow", "RU38" => "Europe/Volgograd",
+        "RU39" => "Asia/Krasnoyarsk", "RU40" => "Asia/Yekaterinburg", "RU41" => "Europe/Moscow",
+        "RU42" => "Europe/Moscow", "RU43" => "Europe/Moscow", "RU44" => "Asia/Magadan",
+        "RU45" => "Europe/Samara", "RU46" => "Europe/Samara", "RU47" => "Europe/Moscow",
+        "RU48" => "Europe/Moscow", "RU49" => "Europe/Moscow", "RU50" => "Asia/Yekaterinburg",
+        "RU51" => "Europe/Moscow", "RU52" => "Europe/Moscow", "RU53" => "Asia/Novosibirsk",
+        "RU54" => "Asia/Omsk", "RU55" => "Europe/Samara", "RU56" => "Europe/Moscow",
+        "RU57" => "Europe/Samara", "RU58" => "Asia/Yekaterinburg", "RU59" => "Asia/Vladivostok",
+        "RU60" => "Europe/Kaliningrad", "RU61" => "Europe/Volgograd", "RU62" => "Europe/Moscow",
+        "RU63" => "Asia/Yakutsk", "RU64" => "Asia/Sakhalin", "RU65" => "Europe/Samara",
+        "RU66" => "Europe/Moscow", "RU67" => "Europe/Samara", "RU68" => "Europe/Volgograd",
+        "RU69" => "Europe/Moscow", "RU70" => "Europe/Volgograd", "RU71" => "Asia/Yekaterinburg",
+        "RU72" => "Europe/Moscow", "RU73" => "Europe/Samara", "RU74" => "Asia/Krasnoyarsk",
+        "RU75" => "Asia/Novosibirsk", "RU76" => "Europe/Moscow", "RU77" => "Europe/Moscow",
+        "RU78" => "Asia/Yekaterinburg", "RU79" => "Asia/Irkutsk", "RU80" => "Asia/Yekaterinburg",
+        "RU81" => "Europe/Samara", "RU82" => "Asia/Irkutsk", "RU83" => "Europe/Moscow",
+        "RU84" => "Europe/Volgograd", "RU85" => "Europe/Moscow", "RU86" => "Europe/Moscow",
+        "RU87" => "Asia/Novosibirsk", "RU88" => "Europe/Moscow", "RU89" => "Asia/Vladivostok",
+        "UA01" => "Europe/Kiev", "UA02" => "Europe/Kiev", "UA03" => "Europe/Uzhgorod",
+        "UA04" => "Europe/Zaporozhye", "UA05" => "Europe/Zaporozhye", "UA06" => "Europe/Uzhgorod",
+        "UA07" => "Europe/Zaporozhye", "UA08" => "Europe/Simferopol", "UA09" => "Europe/Kiev",
+        "UA10" => "Europe/Zaporozhye", "UA11" => "Europe/Simferopol", "UA13" => "Europe/Kiev",
+        "UA14" => "Europe/Zaporozhye", "UA15" => "Europe/Uzhgorod", "UA16" => "Europe/Zaporozhye",
+        "UA17" => "Europe/Simferopol", "UA18" => "Europe/Zaporozhye", "UA19" => "Europe/Kiev",
+        "UA20" => "Europe/Simferopol", "UA21" => "Europe/Kiev", "UA22" => "Europe/Uzhgorod",
+        "UA23" => "Europe/Kiev", "UA24" => "Europe/Uzhgorod", "UA25" => "Europe/Uzhgorod",
+        "UA26" => "Europe/Zaporozhye", "UA27" => "Europe/Kiev", "UZ01" => "Asia/Tashkent",
+        "UZ02" => "Asia/Samarkand", "UZ03" => "Asia/Tashkent", "UZ06" => "Asia/Tashkent",
+        "UZ07" => "Asia/Samarkand", "UZ08" => "Asia/Samarkand", "UZ09" => "Asia/Samarkand",
+        "UZ10" => "Asia/Samarkand", "UZ12" => "Asia/Samarkand", "UZ13" => "Asia/Tashkent",
+        "UZ14" => "Asia/Tashkent", "TL" => "Asia/Dili", "PF" => "Pacific/Marquesas"
+    }
+
+    public
+    # Edition enumeration:
+    (GEOIP_COUNTRY_EDITION,
+    GEOIP_CITY_EDITION_REV1,
+    GEOIP_REGION_EDITION_REV1,
+    GEOIP_ISP_EDITION,
+    GEOIP_ORG_EDITION,
+    GEOIP_CITY_EDITION_REV0,
+    GEOIP_REGION_EDITION_REV0,
+    GEOIP_PROXY_EDITION,
+    GEOIP_ASNUM_EDITION,
+    GEOIP_NETSPEED_EDITION,
+    ) = *1..10
+
+    private
+    COUNTRY_BEGIN = 16776960
+    STATE_BEGIN_REV0 = 16700000
+    STATE_BEGIN_REV1 = 16000000
+    STRUCTURE_INFO_MAX_SIZE = 20
+    DATABASE_INFO_MAX_SIZE = 100
+    MAX_ORG_RECORD_LENGTH = 300
+    MAX_ASN_RECORD_LENGTH = 300 # unverified
+    US_OFFSET = 1
+    CANADA_OFFSET = 677
+    WORLD_OFFSET = 1353
+    FIPS_RANGE = 360
+    FULL_RECORD_LENGTH = 50
+
+    STANDARD_RECORD_LENGTH = 3
+    SEGMENT_RECORD_LENGTH = 3
+
+    public
+    attr_reader :databaseType
+
+    # Open the GeoIP database and determine the file format version
+    #
+    # +filename+ is a String holding the path to the GeoIP.dat file
+    # +options+ is an integer holding caching flags (unimplemented)
+    def initialize(filename, flags = 0)
+        @mutex = IO.respond_to?(:pread) ? false : Mutex.new
+        @flags = flags
+        @databaseType = GEOIP_COUNTRY_EDITION
+        @record_length = STANDARD_RECORD_LENGTH
+        @file = File.open(filename, 'rb')
+        @file.seek(-3, IO::SEEK_END)
+        0.upto(STRUCTURE_INFO_MAX_SIZE-1) { |i|
+            if @file.read(3) == "\xFF\xFF\xFF"
+                @databaseType = @file.respond_to?(:getbyte) ? @file.getbyte : @file.getc
+                @databaseType -= 105 if @databaseType >= 106
+
+                if (@databaseType == GEOIP_REGION_EDITION_REV0)
+                    # Region Edition, pre June 2003
+                    @databaseSegments = [ STATE_BEGIN_REV0 ]
+                elsif (@databaseType == GEOIP_REGION_EDITION_REV1)
+                    # Region Edition, post June 2003
+                    @databaseSegments = [ STATE_BEGIN_REV1 ]
+                elsif (@databaseType == GEOIP_CITY_EDITION_REV0 ||
+                       @databaseType == GEOIP_CITY_EDITION_REV1 ||
+                       @databaseType == GEOIP_ORG_EDITION ||
+                       @databaseType == GEOIP_ISP_EDITION ||
+                       @databaseType == GEOIP_ASNUM_EDITION)
+                    # City/Org Editions have two segments, read offset of second segment
+                    @databaseSegments = [ 0 ]
+                    sr = @file.read(3).unpack("C*")
+                    @databaseSegments[0] += le_to_ui(sr)
+
+                    if (@databaseType == GEOIP_ORG_EDITION ||
+                        @databaseType == GEOIP_ISP_EDITION)
+                        @record_length = 4
+                    end
+                end
+                break
+
+            else
+                @file.seek(-4, IO::SEEK_CUR)
+            end
+        }
+        if (@databaseType == GEOIP_COUNTRY_EDITION ||
+            @databaseType == GEOIP_PROXY_EDITION ||
+            @databaseType == GEOIP_NETSPEED_EDITION)
+            @databaseSegments = [ COUNTRY_BEGIN ]
+        end
+    end
+
+    # Search the GeoIP database for the specified host, returning country info
+    #
+    # +hostname+ is a String holding the host's DNS name or numeric IP address.
+    # Return an array of seven elements:
+    # * The host or IP address string as requested
+    # * The IP address string after looking up the host
+    # * The GeoIP country-ID as an integer
+    # * The ISO3166-1 two-character country code
+    # * The ISO3166-2 three-character country code
+    # * The ISO3166 English-language name of the country
+    # * The two-character continent code
+    #
+    def country(hostname)
+        if (@databaseType == GEOIP_CITY_EDITION_REV0 ||
+            @databaseType == GEOIP_CITY_EDITION_REV1)
+            return city(hostname)
+        end
+
+        ip = hostname
+        if ip.kind_of?(String) && ip !~ /^[0-9.]*$/
+            # Lookup IP address, we were given a name
+            ip = IPSocket.getaddress(hostname)
+            ip = '0.0.0.0' if ip == '::1'
+        end
+
+        # Convert numeric IP address to an integer
+        ipnum = iptonum(ip)
+        if (@databaseType != GEOIP_COUNTRY_EDITION && 
+            @databaseType != GEOIP_PROXY_EDITION &&
+            @databaseType != GEOIP_NETSPEED_EDITION)
+            throw "Invalid GeoIP database type, can't look up Country by IP"
+        end
+        code = seek_record(ipnum) - COUNTRY_BEGIN;
+        [   hostname,                   # Requested hostname
+            ip,                         # Ip address as dotted quad
+            code,                       # GeoIP's country code
+            CountryCode[code],          # ISO3166-1 code
+            CountryCode3[code],         # ISO3166-2 code
+            CountryName[code],          # Country name, per IS03166
+            CountryContinent[code] ]    # Continent code.
+    end
+
+    # Search the GeoIP database for the specified host, returning city info
+    #
+    # +hostname+ is a String holding the host's DNS name or numeric IP address
+    # Return an array of twelve or fourteen elements:
+    # * All elements from the country query
+    # * The region (state or territory) name
+    # * The city name
+    # * The postal code (zipcode)
+    # * The latitude
+    # * The longitude
+    # * The dma_code and area_code, if available (REV1 City database)
+    # * The timezone name, if known
+    private
+
+    def read_city(pos, hostname = '', ip = '')
+        off = pos + (2*@record_length-1) * @databaseSegments[0]
+        record = atomic_read(FULL_RECORD_LENGTH, off)
+        return nil unless record && record.size == FULL_RECORD_LENGTH
+
+        # The country code is the first byte:
+        code = record[0]
+        code = code.ord if code.respond_to?(:ord)
+        record = record[1..-1]
+        @iter_pos += 1 unless @iter_pos.nil?
+
+        spl = record.split("\x00", 4)
+        # Get the region:
+        region = spl[0]
+        @iter_pos += (region.size + 1) unless @iter_pos.nil?
+
+        # Get the city:
+        city = spl[1]
+        @iter_pos += (city.size + 1) unless @iter_pos.nil?
+
+        # Get the postal code:
+        postal_code = spl[2]
+        @iter_pos += (postal_code.size + 1) unless @iter_pos.nil?
+
+        record = spl[3]
+        # Get the latitude/longitude:
+        if(record && record[0,3]) then
+            latitude  = le_to_ui(record[0,3].unpack('C*')) / 10000.0 - 180
+            record = record[3..-1]
+            @iter_pos += 3 unless @iter_pos.nil?
+        else
+            latitude = ''
+        end
+        if(record && record[0,3]) then
+            longitude = le_to_ui(record[0,3].unpack('C*')) / 10000.0 - 180
+            record = record[3..-1]
+            @iter_pos += 3 unless @iter_pos.nil?
+        else
+            longitude = ''
+        end
+
+        us_area_codes = []
+        if (record &&
+                record[0,3] &&
+                @databaseType == GEOIP_CITY_EDITION_REV1 &&
+                CountryCode[code] == "US")      # UNTESTED
+            dmaarea_combo = le_to_ui(record[0,3].unpack('C*'))
+            dma_code = dmaarea_combo / 1000;
+            area_code = dmaarea_combo % 1000;
+            us_area_codes = [ dma_code, area_code ]
+            @iter_pos += 3 unless @iter_pos.nil?
+        else
+            us_area_codes = [ nil, nil ]  # Ensure that TimeZone is always at the same offset
+        end
+
+        [   hostname,                   # Requested hostname
+            ip,                         # Ip address as dotted quad
+            CountryCode[code],          # ISO3166-1 code
+            CountryCode3[code],         # ISO3166-2 code
+            CountryName[code],          # Country name, per IS03166
+            CountryContinent[code],     # Continent code.
+            region,                     # Region name
+            city,                       # City name
+            postal_code,                # Postal code
+            latitude,
+            longitude,
+        ] +
+            us_area_codes +
+            [ TimeZone["#{CountryCode[code]}#{region}"] || TimeZone["#{CountryCode[code]}"] ]
+    end
+
+    public
+
+    # Search the GeoIP database for the specified host, returning city info.
+    #
+    # +hostname+ is a String holding the host's DNS name or numeric IP address.
+    # Return an array of twelve or fourteen elements:
+    # * The host or IP address string as requested
+    # * The IP address string after looking up the host
+    # * The GeoIP country-ID as an integer
+    # * The ISO3166-1 two-character country code
+    # * The ISO3166-2 three-character country code
+    # * The ISO3166 English-language name of the country
+    # * The two-character continent code
+    # * The region name
+    # * The city name
+    # * The postal code
+    # * The latitude
+    # * The longitude
+    # * The USA dma_code and area_code, if available (REV1 City database)
+    #
+    def city(hostname)
+        ip = hostname
+        if ip.kind_of?(String) && ip !~ /^[0-9.]*$/
+            # Lookup IP address, we were given a name
+            ip = IPSocket.getaddress(hostname)
+            ip = '0.0.0.0' if ip == '::1'
+        end
+
+        # Convert numeric IP address to an integer
+        ipnum = iptonum(ip)
+        if (@databaseType != GEOIP_CITY_EDITION_REV0 &&
+            @databaseType != GEOIP_CITY_EDITION_REV1)
+            throw "Invalid GeoIP database type, can't look up City by IP"
+        end
+        pos = seek_record(ipnum);
+        # This next statement was added to MaxMind's C version after it was rewritten in Ruby.
+        # It prevents unassigned IP addresses from returning bogus data.  There was concern over
+        # whether the changes to an application's behaviour were always correct, but this has been
+        # tested using an exhaustive search of the top 16 bits of the IP address space.  The records
+        # where the change takes effect contained *no* valid data.  If you're concerned, email me,
+        # and I'll send you the test program so you can test whatever IP range you think is causing
+        # problems, as I don't care to undertake an exhaustive search of the 32-bit space.
+        return nil if pos == @databaseSegments[0]
+        read_city(pos, hostname, ip)
+    end
+
+    # Search a ISP GeoIP database for the specified host, returning the ISP
+    #
+    # +hostname+ is a String holding the host's DNS name or numeric IP address.
+    # Return the ISP name
+    #
+    def isp(hostname)
+        ip = hostname
+        if ip.kind_of?(String) && ip !~ /^[0-9.]*$/
+            # Lookup IP address, we were given a name
+            ip = IPSocket.getaddress(hostname)
+            ip = '0.0.0.0' if ip == '::1'
+        end
+
+        # Convert numeric IP address to an integer
+        ipnum = iptonum(ip)
+        if @databaseType != GEOIP_ISP_EDITION
+            throw "Invalid GeoIP database type, can't look up Organization/ISP by IP"
+        end
+        pos = seek_record(ipnum);
+        off = pos + (2*@record_length-1) * @databaseSegments[0]
+        record = atomic_read(MAX_ORG_RECORD_LENGTH, off)
+        record = record.sub(/\000.*/n, '')
+        record
+    end
+    
+    # Search a ASN GeoIP database for the specified host, returning the AS number + description
+    #
+    # +hostname+ is a String holding the host's DNS name or numeric IP address.
+    # Return the AS number + description
+    #
+    # Source:
+    # http://geolite.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
+    #   
+    def asn(hostname)
+        ip = hostname
+        if ip.kind_of?(String) && ip !~ /^[0-9.]*$/
+            # Lookup IP address, we were given a name
+            ip = IPSocket.getaddress(hostname)
+            ip = '0.0.0.0' if ip == '::1'
+        end
+
+        # Convert numeric IP address to an integer
+        ipnum = iptonum(ip)
+        if (@databaseType != GEOIP_ASNUM_EDITION)
+            throw "Invalid GeoIP database type, can't look up ASN by IP"
+        end
+        pos = seek_record(ipnum);
+        off = pos + (2*@record_length-1) * @databaseSegments[0]
+        record = atomic_read(MAX_ASN_RECORD_LENGTH, off)
+        record = record.sub(/\000.*/n, '')
+        
+        if record =~ /^(AS\d+)\s(.*)$/
+          # AS####, Description 
+          return [$1, $2]
+        end
+    end
+
+    # Search a ISP GeoIP database for the specified host, returning the organization
+    #
+    # +hostname+ is a String holding the host's DNS name or numeric IP address.
+    # Return the organization associated with it
+    #
+    alias_method(:organization, :isp)     # Untested, according to Maxmind docs this should work
+
+    # Iterate through a GeoIP city database
+    def each
+        if (@databaseType != GEOIP_CITY_EDITION_REV0 &&
+            @databaseType != GEOIP_CITY_EDITION_REV1)
+            throw "Invalid GeoIP database type, can't iterate thru non-City database"
+        end
+
+        @iter_pos = @databaseSegments[0] + 1
+        num = 0
+        until((rec = read_city(@iter_pos)).nil?)
+            yield(rec)
+            print "#{num}: #{@iter_pos}\n" if((num += 1) % 1000 == 0)
+        end
+        @iter_pos = nil
+        self
+    end
+
+    private
+      
+    def iptonum(ip)     # Convert numeric IP address to integer
+        if ip.kind_of?(String) &&
+            ip =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/
+            ip = be_to_ui(Regexp.last_match().to_a.slice(1..4))
+        end
+        ip
+    end
+
+    def seek_record(ipnum)
+        # Binary search in the file.
+        # Records are pairs of little-endian integers, each of @record_length.
+        offset = 0
+        mask = 0x80000000
+        31.downto(0) { |depth|
+            off = @record_length * 2 * offset
+            buf = atomic_read(@record_length * 2, off)
+            buf.slice!(0...@record_length) if ((ipnum & mask) != 0)
+            offset = le_to_ui(buf[0...@record_length].unpack("C*"))
+            return offset if (offset >= @databaseSegments[0])
+            mask >>= 1
+        }
+    end
+
+    # Convert a big-endian array of numeric bytes to unsigned int
+    def be_to_ui(s)
+        s.inject(0) { |m, o|
+            (m << 8) + o.to_i
+        }
+    end
+
+    # Same for little-endian
+    def le_to_ui(s)
+        be_to_ui(s.reverse)
+    end
+
+    # reads +length+ bytes from +offset+ as atomically as possible
+    # if IO.pread is available, it'll use that (making it both multithread
+    # and multiprocess-safe). Otherwise we'll use a mutex to synchronize
+    # access (only providing protection against multiple threads, but not
+    # file descriptors shared across multiple processes).
+    def atomic_read(length, offset)
+        if @mutex
+            @mutex.synchronize {
+                @file.seek(offset)
+                @file.read(length)
+            }
+        else
+            IO.pread(@file.fileno, length, offset)
+        end
+    end
+end
+
+if $0 == __FILE__
+    data = '/usr/share/GeoIP/GeoIP.dat'
+    data = ARGV.shift if ARGV[0] =~ /\.dat\Z/
+    g = GeoIP.new data
+
+    req = ([GeoIP::GEOIP_CITY_EDITION_REV1, GeoIP::GEOIP_CITY_EDITION_REV0].include?(g.databaseType)) ? :city : :country
+    ARGV.each { |a|
+        p g.send(req, a)
+    }
+end
+

Added: cdn/trunk/geoip/script/destroy
===================================================================
--- cdn/trunk/geoip/script/destroy	                        (rev 0)
+++ cdn/trunk/geoip/script/destroy	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,14 @@
+#!/usr/bin/env ruby
+APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+
+begin
+  require 'rubigen'
+rescue LoadError
+  require 'rubygems'
+  require 'rubigen'
+end
+require 'rubigen/scripts/destroy'
+
+ARGV.shift if ['--help', '-h'].include?(ARGV[0])
+RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
+RubiGen::Scripts::Destroy.new.run(ARGV)

Added: cdn/trunk/geoip/script/generate
===================================================================
--- cdn/trunk/geoip/script/generate	                        (rev 0)
+++ cdn/trunk/geoip/script/generate	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,14 @@
+#!/usr/bin/env ruby
+APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+
+begin
+  require 'rubigen'
+rescue LoadError
+  require 'rubygems'
+  require 'rubigen'
+end
+require 'rubigen/scripts/generate'
+
+ARGV.shift if ['--help', '-h'].include?(ARGV[0])
+RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
+RubiGen::Scripts::Generate.new.run(ARGV)

Added: cdn/trunk/geoip/script/txt2html
===================================================================
--- cdn/trunk/geoip/script/txt2html	                        (rev 0)
+++ cdn/trunk/geoip/script/txt2html	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,74 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+begin
+  require 'newgem'
+rescue LoadError
+  puts "\n\nGenerating the website requires the newgem RubyGem"
+  puts "Install: gem install newgem\n\n"
+  exit(1)
+end
+require 'redcloth'
+require 'syntax/convertors/html'
+require 'erb'
+require File.dirname(__FILE__) + '/../lib/geoip.rb'
+
+version  = GeoIP::VERSION
+download = 'http://rubyforge.org/projects/geoip'
+
+class Fixnum
+  def ordinal
+    # teens
+    return 'th' if (10..19).include?(self % 100)
+    # others
+    case self % 10
+    when 1: return 'st'
+    when 2: return 'nd'
+    when 3: return 'rd'
+    else    return 'th'
+    end
+  end
+end
+
+class Time
+  def pretty
+    return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
+  end
+end
+
+def convert_syntax(syntax, source)
+  return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
+end
+
+if ARGV.length >= 1
+  src, template = ARGV
+  template ||= File.join(File.dirname(__FILE__), '/../website/template.rhtml')
+  
+else
+  puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
+  exit!
+end
+
+template = ERB.new(File.open(template).read)
+
+title = nil
+body = nil
+File.open(src) do |fsrc|
+  title_text = fsrc.readline
+  body_text = fsrc.read
+  syntax_items = []
+  body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
+    ident = syntax_items.length
+    element, syntax, source = $1, $2, $3
+    syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
+    "syntax-temp-#{ident}"
+  }
+  title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
+  body = RedCloth.new(body_text).to_html
+  body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
+end
+stat = File.stat(src)
+created = stat.ctime
+modified = stat.mtime
+
+$stdout << template.result(binding)

Added: cdn/trunk/geoip/tasks/website.rake
===================================================================
--- cdn/trunk/geoip/tasks/website.rake	                        (rev 0)
+++ cdn/trunk/geoip/tasks/website.rake	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,17 @@
+desc 'Generate website files'
+task :website_generate => :ruby_env do
+  (Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
+    sh %{ #{ENV['RUBY_APP']||'ruby'} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
+  end
+end
+
+desc 'Upload website files to rubyforge'
+task :website_upload do
+  host = "#{rubyforge_username}@rubyforge.org"
+  remote_dir = "/var/www/gforge-projects/#{PATH}/"
+  local_dir = 'website'
+  sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
+end
+
+desc 'Generate and upload website files'
+task :website => [:website_generate, :website_upload, :publish_docs]

Added: cdn/trunk/geoip/test/test_geoip.rb
===================================================================
--- cdn/trunk/geoip/test/test_geoip.rb	                        (rev 0)
+++ cdn/trunk/geoip/test/test_geoip.rb	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/test_helper.rb'
+
+class TestGeoip < Test::Unit::TestCase
+
+  def setup
+  end
+  
+  def test_truth
+    assert true
+  end
+end

Added: cdn/trunk/geoip/test/test_helper.rb
===================================================================
--- cdn/trunk/geoip/test/test_helper.rb	                        (rev 0)
+++ cdn/trunk/geoip/test/test_helper.rb	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,3 @@
+require 'stringio'
+require 'test/unit'
+require File.dirname(__FILE__) + '/../lib/geoip'

Added: cdn/trunk/geoip/website/index.txt
===================================================================
--- cdn/trunk/geoip/website/index.txt	                        (rev 0)
+++ cdn/trunk/geoip/website/index.txt	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,65 @@
+h1. geoip
+
+h2. 'Geographic info for an IP address'
+
+h2. What
+
+GeoIP searches a GeoIP database for a given host or IP address, and
+returns information about the country where the IP address is allocated,
+and the city, ISP and other information, if you have that database version.
+
+h2. Installing
+
+<pre syntax="ruby">sudo gem install geoip</pre>
+
+h2. Prerequisites
+
+You need at least the free GeoIP.dat, for which the last known download
+location is "http://www.maxmind.com/download/geoip/database/GeoIP.dat.gz":http://www.maxmind.com/download/geoip/database/GeoIP.dat.gz
+or the city database "http://www.maxmind.com/app/geolitecity":http://www.maxmind.com/app/geolitecity
+This API requires the file to be decompressed for searching. Other versions
+of this database are available for purchase which contain more detailed
+information, but this information is not returned by this implementation.
+See www.maxmind.com for more information.
+
+h2. Example
+
+    <pre>
+    require 'geoip'
+    GeoIP.new('GeoIP.dat').country("www.netscape.sk")
+    => ["www.netscape.sk", "217.67.16.35", 196, "SK", "SVK", "Slovakia", "EU"]
+
+
+    GeoIP.new('GeoCity.dat').city('github.com')
+    => ["github.com", "207.97.227.239", "US", "USA", "United States", "NA", "CA", "San Francisco", "94110", 37.7484, -122.4156, "America/Los_Angeles", 807, 415]
+
+
+    GeoIP.new('GeoIPASNum.dat').asn("www.fsb.ru")
+    => ["AS8342", "RTComm.RU Autonomous System"]
+    </pre>
+
+h2. Source Repository
+
+The trunk repository is <code>http://github.com/cjheath/geoip</code>
+
+h2. License
+
+I don't normally use the GPL license, but this one is derived
+from Maxmind's code, so I use the license they use.
+
+This version Copyright (C) 2005 Clifford Heath
+Derived from the C version, Copyright (C) 2003 MaxMind LLC
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Added: cdn/trunk/geoip/website/javascripts/rounded_corners_lite.inc.js
===================================================================
--- cdn/trunk/geoip/website/javascripts/rounded_corners_lite.inc.js	                        (rev 0)
+++ cdn/trunk/geoip/website/javascripts/rounded_corners_lite.inc.js	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,285 @@
+
+ /****************************************************************
+  *                                                              *
+  *  curvyCorners                                                *
+  *  ------------                                                *
+  *                                                              *
+  *  This script generates rounded corners for your divs.        *
+  *                                                              *
+  *  Version 1.2.9                                               *
+  *  Copyright (c) 2006 Cameron Cooke                            *
+  *  By: Cameron Cooke and Tim Hutchison.                        *
+  *                                                              *
+  *                                                              *
+  *  Website: http://www.curvycorners.net                        *
+  *  Email:   info@xxxxxxxxxxxxxxxxx                             *
+  *  Forum:   http://www.curvycorners.net/forum/                 *
+  *                                                              *
+  *                                                              *
+  *  This library is free software; you can redistribute         *
+  *  it and/or modify it under the terms of the GNU              *
+  *  Lesser General Public License as published by the           *
+  *  Free Software Foundation; either version 2.1 of the         *
+  *  License, or (at your option) any later version.             *
+  *                                                              *
+  *  This library is distributed in the hope that it will        *
+  *  be useful, but WITHOUT ANY WARRANTY; without even the       *
+  *  implied warranty of MERCHANTABILITY or FITNESS FOR A        *
+  *  PARTICULAR PURPOSE. See the GNU Lesser General Public       *
+  *  License for more details.                                   *
+  *                                                              *
+  *  You should have received a copy of the GNU Lesser           *
+  *  General Public License along with this library;             *
+  *  Inc., 59 Temple Place, Suite 330, Boston,                   *
+  *  MA 02111-1307 USA                                           *
+  *                                                              *
+  ****************************************************************/
+  
+var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()
+{ if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if(typeof(arguments[1]) == "string")
+{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}
+else
+{ var startIndex = 1; var boxCol = arguments;}
+var curvyCornersCol = new Array(); if(arguments[0].validTags)
+var validElements = arguments[0].validTags; else
+var validElements = ["div"]; for(var i = startIndex, j = boxCol.length; i < j; i++)
+{ var currentTag = boxCol[i].tagName.toLowerCase(); if(inArray(validElements, currentTag) !== false)
+{ curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);}
+}
+this.objects = curvyCornersCol; this.applyCornersToAll = function()
+{ for(var x = 0, k = this.objects.length; x < k; x++)
+{ this.objects[x].applyCorners();}
+}
+}
+function curvyObject()
+{ this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.contentDIV = null; var boxHeight = get_style(this.box, "height", "height"); var boxWidth = get_style(this.box, "width", "width"); var borderWidth = get_style(this.box, "borderTopWidth", "border-top-width"); var borderColour = get_style(this.box, "borderTopColor", "border-top-color"); var boxColour = get_style(this.box, "backgroundColor", "background-color"); var backgroundImage = get_style(this.box, "backgroundImage", "background-image"); var boxPosition = get_style(this.box, "position", "position"); var boxPadding = get_style(this.box, "paddingTop", "padding-top"); this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight)); this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth)); this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0)); this.boxColour = format_colour(boxColour); this.boxPadding = parseInt(((boxPadding != "" && boxPadding.indexOf("px") !== -1)? boxPadding.slice(0, boxPadding.indexOf("px")) : 0)); this.borderColour = format_colour(borderColour); this.borderString = this.borderWidth + "px" + " solid " + this.borderColour; this.backgroundImage = ((backgroundImage != "none")? backgroundImage : ""); this.boxContent = this.box.innerHTML; if(boxPosition != "absolute") this.box.style.position = "relative"; this.box.style.padding = "0px"; if(isIE && boxWidth == "auto" && boxHeight == "auto") this.box.style.width = "100%"; if(this.settings.autoPad == true && this.boxPadding > 0)
+this.box.innerHTML = ""; this.applyCorners = function()
+{ for(var t = 0; t < 2; t++)
+{ switch(t)
+{ case 0:
+if(this.settings.tl || this.settings.tr)
+{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); newMainContainer.style.height = topMaxRadius + "px"; newMainContainer.style.top = 0 - topMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.topContainer = this.box.appendChild(newMainContainer);}
+break; case 1:
+if(this.settings.bl || this.settings.br)
+{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); newMainContainer.style.height = botMaxRadius + "px"; newMainContainer.style.bottom = 0 - botMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.bottomContainer = this.box.appendChild(newMainContainer);}
+break;}
+}
+if(this.topContainer) this.box.style.borderTopWidth = "0px"; if(this.bottomContainer) this.box.style.borderBottomWidth = "0px"; var corners = ["tr", "tl", "br", "bl"]; for(var i in corners)
+{ if(i > -1 < 4)
+{ var cc = corners[i]; if(!this.settings[cc])
+{ if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null))
+{ var newCorner = document.createElement("DIV"); newCorner.style.position = "relative"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; if(this.backgroundImage == "")
+newCorner.style.backgroundColor = this.boxColour; else
+newCorner.style.backgroundImage = this.backgroundImage; switch(cc)
+{ case "tl":
+newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.left = -this.borderWidth + "px"; break; case "tr":
+newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; newCorner.style.left = this.borderWidth + "px"; break; case "bl":
+newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = -this.borderWidth + "px"; newCorner.style.backgroundPosition = "-" + (this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break; case "br":
+newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = this.borderWidth + "px"
+newCorner.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break;}
+}
+}
+else
+{ if(this.masterCorners[this.settings[cc].radius])
+{ var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);}
+else
+{ var newCorner = document.createElement("DIV"); newCorner.style.height = this.settings[cc].radius + "px"; newCorner.style.width = this.settings[cc].radius + "px"; newCorner.style.position = "absolute"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth); for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)
+{ if((intx +1) >= borderRadius)
+var y1 = -1; else
+var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1); if(borderRadius != j)
+{ if((intx) >= borderRadius)
+var y2 = -1; else
+var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2))); if((intx+1) >= j)
+var y3 = -1; else
+var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);}
+if((intx) >= j)
+var y4 = -1; else
+var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2))); if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius); if(borderRadius != j)
+{ for(var inty = (y1 + 1); inty < y2; inty++)
+{ if(this.settings.antiAlias)
+{ if(this.backgroundImage != "")
+{ var borderFract = (pixelFraction(intx, inty, borderRadius) * 100); if(borderFract < 30)
+{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);}
+else
+{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);}
+}
+else
+{ var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius)); this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, cc);}
+}
+}
+if(this.settings.antiAlias)
+{ if(y3 >= y2)
+{ if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0);}
+}
+else
+{ if(y3 >= y1)
+{ this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0);}
+}
+var outsideColour = this.borderColour;}
+else
+{ var outsideColour = this.boxColour; var y3 = y1;}
+if(this.settings.antiAlias)
+{ for(var inty = (y3 + 1); inty < y4; inty++)
+{ this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);}
+}
+}
+this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);}
+if(cc != "br")
+{ for(var t = 0, k = newCorner.childNodes.length; t < k; t++)
+{ var pixelBar = newCorner.childNodes[t]; var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px"))); var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px"))); var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px"))); if(cc == "tl" || cc == "bl"){ pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px";}
+if(cc == "tr" || cc == "tl"){ pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px";}
+switch(cc)
+{ case "tr":
+pixelBar.style.backgroundPosition = "-" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "tl":
+pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "bl":
+pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px"; break;}
+}
+}
+}
+if(newCorner)
+{ switch(cc)
+{ case "tl":
+if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "tr":
+if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "bl":
+if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break; case "br":
+if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break;}
+}
+}
+}
+var radiusDiff = new Array(); radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)
+radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for(z in radiusDiff)
+{ if(z == "t" || z == "b")
+{ if(radiusDiff[z])
+{ var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r"); var newFiller = document.createElement("DIV"); newFiller.style.height = radiusDiff[z] + "px"; newFiller.style.width = this.settings[smallerCornerType].radius+ "px"
+newFiller.style.position = "absolute"; newFiller.style.fontSize = "1px"; newFiller.style.overflow = "hidden"; newFiller.style.backgroundColor = this.boxColour; switch(smallerCornerType)
+{ case "tl":
+newFiller.style.bottom = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.topContainer.appendChild(newFiller); break; case "tr":
+newFiller.style.bottom = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.topContainer.appendChild(newFiller); break; case "bl":
+newFiller.style.top = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.bottomContainer.appendChild(newFiller); break; case "br":
+newFiller.style.top = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.bottomContainer.appendChild(newFiller); break;}
+}
+var newFillerBar = document.createElement("DIV"); newFillerBar.style.position = "relative"; newFillerBar.style.fontSize = "1px"; newFillerBar.style.overflow = "hidden"; newFillerBar.style.backgroundColor = this.boxColour; newFillerBar.style.backgroundImage = this.backgroundImage; switch(z)
+{ case "t":
+if(this.topContainer)
+{ if(this.settings.tl.radius && this.settings.tr.radius)
+{ newFillerBar.style.height = topMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + "px"; newFillerBar.style.borderTop = this.borderString; if(this.backgroundImage != "")
+newFillerBar.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; this.topContainer.appendChild(newFillerBar);}
+this.box.style.backgroundPosition = "0px -" + (topMaxRadius - this.borderWidth) + "px";}
+break; case "b":
+if(this.bottomContainer)
+{ if(this.settings.bl.radius && this.settings.br.radius)
+{ newFillerBar.style.height = botMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + "px"; newFillerBar.style.borderBottom = this.borderString; if(this.backgroundImage != "")
+newFillerBar.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + "px"; this.bottomContainer.appendChild(newFillerBar);}
+}
+break;}
+}
+}
+if(this.settings.autoPad == true && this.boxPadding > 0)
+{ var contentContainer = document.createElement("DIV"); contentContainer.style.position = "relative"; contentContainer.innerHTML = this.boxContent; contentContainer.className = "autoPadDiv"; var topPadding = Math.abs(topMaxRadius - this.boxPadding); var botPadding = Math.abs(botMaxRadius - this.boxPadding); if(topMaxRadius < this.boxPadding)
+contentContainer.style.paddingTop = topPadding + "px"; if(botMaxRadius < this.boxPadding)
+contentContainer.style.paddingBottom = botMaxRadius + "px"; contentContainer.style.paddingLeft = this.boxPadding + "px"; contentContainer.style.paddingRight = this.boxPadding + "px"; this.contentDIV = this.box.appendChild(contentContainer);}
+}
+this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius)
+{ var pixel = document.createElement("DIV"); pixel.style.height = height + "px"; pixel.style.width = "1px"; pixel.style.position = "absolute"; pixel.style.fontSize = "1px"; pixel.style.overflow = "hidden"; var topMaxRadius = Math.max(this.settings["tr"].radius, this.settings["tl"].radius); if(image == -1 && this.backgroundImage != "")
+{ pixel.style.backgroundImage = this.backgroundImage; pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + "px";}
+else
+{ pixel.style.backgroundColor = colour;}
+if (transAmount != 100)
+setOpacity(pixel, transAmount); pixel.style.top = inty + "px"; pixel.style.left = intx + "px"; newCorner.appendChild(pixel);}
+}
+function insertAfter(parent, node, referenceNode)
+{ parent.insertBefore(node, referenceNode.nextSibling);}
+function BlendColour(Col1, Col2, Col1Fraction)
+{ var red1 = parseInt(Col1.substr(1,2),16); var green1 = parseInt(Col1.substr(3,2),16); var blue1 = parseInt(Col1.substr(5,2),16); var red2 = parseInt(Col2.substr(1,2),16); var green2 = parseInt(Col2.substr(3,2),16); var blue2 = parseInt(Col2.substr(5,2),16); if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1; var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction))); if(endRed > 255) endRed = 255; if(endRed < 0) endRed = 0; var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction))); if(endGreen > 255) endGreen = 255; if(endGreen < 0) endGreen = 0; var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction))); if(endBlue > 255) endBlue = 255; if(endBlue < 0) endBlue = 0; return "#" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);}
+function IntToHex(strNum)
+{ base = strNum / 16; rem = strNum % 16; base = base - (rem / 16); baseS = MakeHex(base); remS = MakeHex(rem); return baseS + '' + remS;}
+function MakeHex(x)
+{ if((x >= 0) && (x <= 9))
+{ return x;}
+else
+{ switch(x)
+{ case 10: return "A"; case 11: return "B"; case 12: return "C"; case 13: return "D"; case 14: return "E"; case 15: return "F";}
+}
+}
+function pixelFraction(x, y, r)
+{ var pixelfraction = 0; var xvalues = new Array(1); var yvalues = new Array(1); var point = 0; var whatsides = ""; var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2))); if ((intersect >= y) && (intersect < (y+1)))
+{ whatsides = "Left"; xvalues[point] = 0; yvalues[point] = intersect - y; point = point + 1;}
+var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2))); if ((intersect >= x) && (intersect < (x+1)))
+{ whatsides = whatsides + "Top"; xvalues[point] = intersect - x; yvalues[point] = 1; point = point + 1;}
+var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2))); if ((intersect >= y) && (intersect < (y+1)))
+{ whatsides = whatsides + "Right"; xvalues[point] = 1; yvalues[point] = intersect - y; point = point + 1;}
+var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2))); if ((intersect >= x) && (intersect < (x+1)))
+{ whatsides = whatsides + "Bottom"; xvalues[point] = intersect - x; yvalues[point] = 0;}
+switch (whatsides)
+{ case "LeftRight":
+pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2); break; case "TopRight":
+pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2); break; case "TopBottom":
+pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2); break; case "LeftBottom":
+pixelfraction = (yvalues[0]*xvalues[1])/2; break; default:
+pixelfraction = 1;}
+return pixelfraction;}
+function rgb2Hex(rgbColour)
+{ try{ var rgbArray = rgb2Array(rgbColour); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);}
+catch(e){ alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");}
+return hexColour;}
+function rgb2Array(rgbColour)
+{ var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")")); var rgbArray = rgbValues.split(", "); return rgbArray;}
+function setOpacity(obj, opacity)
+{ opacity = (opacity == 100)?99.999:opacity; if(isSafari && obj.tagName != "IFRAME")
+{ var rgbArray = rgb2Array(obj.style.backgroundColor); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";}
+else if(typeof(obj.style.opacity) != "undefined")
+{ obj.style.opacity = opacity/100;}
+else if(typeof(obj.style.MozOpacity) != "undefined")
+{ obj.style.MozOpacity = opacity/100;}
+else if(typeof(obj.style.filter) != "undefined")
+{ obj.style.filter = "alpha(opacity:" + opacity + ")";}
+else if(typeof(obj.style.KHTMLOpacity) != "undefined")
+{ obj.style.KHTMLOpacity = opacity/100;}
+}
+function inArray(array, value)
+{ for(var i = 0; i < array.length; i++){ if (array[i] === value) return i;}
+return false;}
+function inArrayKey(array, value)
+{ for(key in array){ if(key === value) return true;}
+return false;}
+function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true;}
+else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r;}
+else { elm['on' + evType] = fn;}
+}
+function removeEvent(obj, evType, fn, useCapture){ if (obj.removeEventListener){ obj.removeEventListener(evType, fn, useCapture); return true;} else if (obj.detachEvent){ var r = obj.detachEvent("on"+evType, fn); return r;} else { alert("Handler could not be removed");}
+}
+function format_colour(colour)
+{ var returnColour = "#ffffff"; if(colour != "" && colour != "transparent")
+{ if(colour.substr(0, 3) == "rgb")
+{ returnColour = rgb2Hex(colour);}
+else if(colour.length == 4)
+{ returnColour = "#" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);}
+else
+{ returnColour = colour;}
+}
+return returnColour;}
+function get_style(obj, property, propertyNS)
+{ try
+{ if(obj.currentStyle)
+{ var returnVal = eval("obj.currentStyle." + property);}
+else
+{ if(isSafari && obj.style.display == "none")
+{ obj.style.display = ""; var wasHidden = true;}
+var returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS); if(isSafari && wasHidden)
+{ obj.style.display = "none";}
+}
+}
+catch(e)
+{ }
+return returnVal;}
+function getElementsByClass(searchClass, node, tag)
+{ var classElements = new Array(); if(node == null)
+node = document; if(tag == null)
+tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)"); for (i = 0, j = 0; i < elsLen; i++)
+{ if(pattern.test(els[i].className))
+{ classElements[j] = els[i]; j++;}
+}
+return classElements;}
+function newCurvyError(errorMessage)
+{ return new Error("curvyCorners Error:\n" + errorMessage)
+}

Added: cdn/trunk/geoip/website/stylesheets/screen.css
===================================================================
--- cdn/trunk/geoip/website/stylesheets/screen.css	                        (rev 0)
+++ cdn/trunk/geoip/website/stylesheets/screen.css	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,138 @@
+body {
+  background-color: #E1D1F1;
+  font-family: "Georgia", sans-serif;
+  font-size: 16px;
+  line-height: 1.6em;
+  padding: 1.6em 0 0 0;
+  color: #333;
+}
+h1, h2, h3, h4, h5, h6 {
+  color: #444;
+}
+h1 { 
+  font-family: sans-serif;
+  font-weight: normal;
+  font-size: 4em;
+  line-height: 0.8em;
+  letter-spacing: -0.1ex;
+	margin: 5px;
+}
+li {
+  padding: 0;
+  margin: 0;
+  list-style-type: square;
+}
+a {
+  color: #5E5AFF;
+	background-color: #DAC;
+  font-weight: normal;
+  text-decoration: underline;
+}
+blockquote {
+  font-size: 90%;
+  font-style: italic;
+  border-left: 1px solid #111;
+  padding-left: 1em;
+}
+.caps {
+  font-size: 80%;
+}
+
+#main {
+  width: 45em;
+  padding: 0;
+  margin: 0 auto;
+}
+.coda {
+  text-align: right;
+  color: #77f;
+  font-size: smaller;
+}
+
+table {
+  font-size: 90%;
+  line-height: 1.4em;
+  color: #ff8;
+  background-color: #111;
+  padding: 2px 10px 2px 10px;
+	border-style: dashed;
+}
+
+th {
+	color: #fff;
+}
+
+td {
+  padding: 2px 10px 2px 10px;
+}
+
+.success {
+	color: #0CC52B;
+}
+
+.failed {
+	color: #E90A1B;
+}
+
+.unknown {
+	color: #995000;
+}
+pre, code {
+  font-family: monospace;
+  font-size: 90%;
+  line-height: 1.4em;
+  color: #ff8;
+  background-color: #111;
+  padding: 2px 10px 2px 10px;
+}
+.comment { color: #aaa; font-style: italic; }
+.keyword { color: #eff; font-weight: bold; }
+.punct { color: #eee; font-weight: bold; }
+.symbol { color: #0bb; }
+.string { color: #6b4; }
+.ident { color: #ff8; }
+.constant { color: #66f; }
+.regex { color: #ec6; }
+.number { color: #F99; }
+.expr { color: #227; }
+
+#version {
+  float: right;
+  text-align: right;
+  font-family: sans-serif;
+  font-weight: normal;
+  background-color: #B3ABFF;
+  color: #141331;
+  padding: 15px 20px 10px 20px;
+  margin: 0 auto;
+	margin-top: 15px;
+  border: 3px solid #141331;
+}
+
+#version .numbers {
+  display: block;
+  font-size: 4em;
+  line-height: 0.8em;
+  letter-spacing: -0.1ex;
+	margin-bottom: 15px;
+}
+
+#version p {
+  text-decoration: none;
+	color: #141331;
+	background-color: #B3ABFF;
+	margin: 0;
+	padding: 0;
+}
+
+#version a {
+  text-decoration: none;
+	color: #141331;
+	background-color: #B3ABFF;
+}
+
+.clickable {
+	cursor:	pointer; 
+	cursor:	hand;
+}
+

Added: cdn/trunk/geoip/website/template.rhtml
===================================================================
--- cdn/trunk/geoip/website/template.rhtml	                        (rev 0)
+++ cdn/trunk/geoip/website/template.rhtml	2010-09-23 11:25:33 UTC (rev 1082)
@@ -0,0 +1,48 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
+<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
+<head>
+  <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>
+      <%= title %>
+  </title>
+  <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
+<style>
+
+</style>
+  <script type="text/javascript">
+    window.onload = function() {
+      settings = {
+          tl: { radius: 10 },
+          tr: { radius: 10 },
+          bl: { radius: 10 },
+          br: { radius: 10 },
+          antiAlias: true,
+          autoPad: true,
+          validTags: ["div"]
+      }
+      var versionBox = new curvyCorners(settings, document.getElementById("version"));
+      versionBox.applyCornersToAll();
+    }
+  </script>
+</head>
+<body>
+<div id="main">
+
+    <h1><%= title %></h1>
+    <div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
+      <p>Get Version</p>
+      <a href="<%= download %>" class="numbers"><%= version %></a>
+    </div>
+    <%= body %>
+    <p class="coda">
+      <a href="cjheath@xxxxxxxxxxxxx">Clifford Heath</a>, <%= modified.pretty %><br>
+      Theme extended from <a href="http://rb2js.rubyforge.org/";>Paul Battley</a>
+    </p>
+</div>
+
+<!-- insert site tracking codes here, like Google Urchin -->
+
+</body>
+</html>