summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Godeps/_workspace/src/github.com/anachronistic/apns/README.md223
-rw-r--r--Godeps/_workspace/src/github.com/braintree/manners/README.md33
-rw-r--r--Godeps/_workspace/src/github.com/go-gorp/gorp/README.md685
-rw-r--r--Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md376
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/context/README.md7
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/mux/README.md7
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/README.md59
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md13
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md19
-rw-r--r--Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md9
-rw-r--r--Godeps/_workspace/src/github.com/huandu/facebook/README.md347
-rw-r--r--Godeps/_workspace/src/github.com/mssola/user_agent/README.md51
-rw-r--r--Godeps/_workspace/src/github.com/nfnt/resize/README.md149
-rw-r--r--Godeps/_workspace/src/github.com/stretchr/objx/README.md3
-rw-r--r--Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md70
-rw-r--r--Godeps/_workspace/src/gopkg.in/bufio.v1/README.md4
-rw-r--r--Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md59
-rw-r--r--Godeps/_workspace/src/gopkg.in/redis.v2/README.md46
-rw-r--r--LICENSE.txt2
-rw-r--r--README.md128
20 files changed, 2289 insertions, 1 deletions
diff --git a/Godeps/_workspace/src/github.com/anachronistic/apns/README.md b/Godeps/_workspace/src/github.com/anachronistic/apns/README.md
new file mode 100644
index 000000000..02b012fd3
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/anachronistic/apns/README.md
@@ -0,0 +1,223 @@
+# apns
+
+Utilities for Apple Push Notification and Feedback Services.
+
+[![GoDoc](https://godoc.org/github.com/anachronistic/apns?status.png)](https://godoc.org/github.com/anachronistic/apns)
+
+## Installation
+
+`go get github.com/anachronistic/apns`
+
+## Documentation
+
+- [APNS package documentation](http://godoc.org/github.com/anachronistic/apns)
+- [Information on the APN JSON payloads](http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html)
+- [Information on the APN binary protocols](http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html)
+- [Information on APN troubleshooting](http://developer.apple.com/library/ios/#technotes/tn2265/_index.html)
+
+## Usage
+
+### Creating pns and payloads manually
+```go
+package main
+
+import (
+ "fmt"
+ apns "github.com/anachronistic/apns"
+)
+
+func main() {
+ payload := apns.NewPayload()
+ payload.Alert = "Hello, world!"
+ payload.Badge = 42
+ payload.Sound = "bingbong.aiff"
+
+ pn := apns.NewPushNotification()
+ pn.AddPayload(payload)
+
+ alert, _ := pn.PayloadString()
+ fmt.Println(alert)
+}
+```
+
+#### Returns
+```json
+{
+ "aps": {
+ "alert": "Hello, world!",
+ "badge": 42,
+ "sound": "bingbong.aiff"
+ }
+}
+```
+
+### Using an alert dictionary for complex payloads
+```go
+package main
+
+import (
+ "fmt"
+ apns "github.com/anachronistic/apns"
+)
+
+func main() {
+ args := make([]string, 1)
+ args[0] = "localized args"
+
+ dict := apns.NewAlertDictionary()
+ dict.Body = "Alice wants Bob to join in the fun!"
+ dict.ActionLocKey = "Play a Game!"
+ dict.LocKey = "localized key"
+ dict.LocArgs = args
+ dict.LaunchImage = "image.jpg"
+
+ payload := apns.NewPayload()
+ payload.Alert = dict
+ payload.Badge = 42
+ payload.Sound = "bingbong.aiff"
+
+ pn := apns.NewPushNotification()
+ pn.AddPayload(payload)
+
+ alert, _ := pn.PayloadString()
+ fmt.Println(alert)
+}
+```
+
+#### Returns
+```json
+{
+ "aps": {
+ "alert": {
+ "body": "Alice wants Bob to join in the fun!",
+ "action-loc-key": "Play a Game!",
+ "loc-key": "localized key",
+ "loc-args": [
+ "localized args"
+ ],
+ "launch-image": "image.jpg"
+ },
+ "badge": 42,
+ "sound": "bingbong.aiff"
+ }
+}
+```
+
+### Setting custom properties
+```go
+package main
+
+import (
+ "fmt"
+ apns "github.com/anachronistic/apns"
+)
+
+func main() {
+ payload := apns.NewPayload()
+ payload.Alert = "Hello, world!"
+ payload.Badge = 42
+ payload.Sound = "bingbong.aiff"
+
+ pn := apns.NewPushNotification()
+ pn.AddPayload(payload)
+
+ pn.Set("foo", "bar")
+ pn.Set("doctor", "who?")
+ pn.Set("the_ultimate_answer", 42)
+
+ alert, _ := pn.PayloadString()
+ fmt.Println(alert)
+}
+```
+
+#### Returns
+```json
+{
+ "aps": {
+ "alert": "Hello, world!",
+ "badge": 42,
+ "sound": "bingbong.aiff"
+ },
+ "doctor": "who?",
+ "foo": "bar",
+ "the_ultimate_answer": 42
+}
+```
+
+### Sending a notification
+```go
+package main
+
+import (
+ "fmt"
+ apns "github.com/anachronistic/apns"
+)
+
+func main() {
+ payload := apns.NewPayload()
+ payload.Alert = "Hello, world!"
+ payload.Badge = 42
+ payload.Sound = "bingbong.aiff"
+
+ pn := apns.NewPushNotification()
+ pn.DeviceToken = "YOUR_DEVICE_TOKEN_HERE"
+ pn.AddPayload(payload)
+
+ client := apns.NewClient("gateway.sandbox.push.apple.com:2195", "YOUR_CERT_PEM", "YOUR_KEY_NOENC_PEM")
+ resp := client.Send(pn)
+
+ alert, _ := pn.PayloadString()
+ fmt.Println(" Alert:", alert)
+ fmt.Println("Success:", resp.Success)
+ fmt.Println(" Error:", resp.Error)
+}
+```
+
+#### Returns
+```shell
+ Alert: {"aps":{"alert":"Hello, world!","badge":42,"sound":"bingbong.aiff"}}
+Success: true
+ Error: <nil>
+```
+
+### Checking the feedback service
+```go
+package main
+
+import (
+ "fmt"
+ apns "github.com/anachronistic/apns"
+ "os"
+)
+
+func main() {
+ fmt.Println("- connecting to check for deactivated tokens (maximum read timeout =", apns.FeedbackTimeoutSeconds, "seconds)")
+
+ client := apns.NewClient("feedback.sandbox.push.apple.com:2196", "YOUR_CERT_PEM", "YOUR_KEY_NOENC_PEM")
+ go client.ListenForFeedback()
+
+ for {
+ select {
+ case resp := <-apns.FeedbackChannel:
+ fmt.Println("- recv'd:", resp.DeviceToken)
+ case <-apns.ShutdownChannel:
+ fmt.Println("- nothing returned from the feedback service")
+ os.Exit(1)
+ }
+ }
+}
+```
+
+#### Returns
+```shell
+- connecting to check for deactivated tokens (maximum read timeout = 5 seconds)
+- nothing returned from the feedback service
+exit status 1
+```
+
+Your output will differ if the service returns device tokens.
+
+```shell
+- recv'd: DEVICE_TOKEN_HERE
+...etc.
+```
diff --git a/Godeps/_workspace/src/github.com/braintree/manners/README.md b/Godeps/_workspace/src/github.com/braintree/manners/README.md
new file mode 100644
index 000000000..8c9a239b4
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/braintree/manners/README.md
@@ -0,0 +1,33 @@
+# Manners
+
+A *polite* webserver for Go.
+
+Manners allows you to shut your Go webserver down gracefully, without dropping any requests. It can act as a drop-in replacement for the standard library's http.ListenAndServe function:
+
+```go
+func main() {
+ handler := MyHTTPHandler()
+ server := manners.NewServer()
+ server.ListenAndServe(":7000", handler)
+}
+```
+
+Then, when you want to shut the server down:
+
+```go
+server.Shutdown <- true
+```
+
+(Note that this does not block until all the requests are finished. Rather, the call to server.ListenAndServe will stop blocking when all the requests are finished.)
+
+Manners ensures that all requests are served by incrementing a WaitGroup when a request comes in and decrementing it when the request finishes.
+
+If your request handler spawns Goroutines that are not guaranteed to finish with the request, you can ensure they are also completed with the `StartRoutine` and `FinishRoutine` functions on the server.
+
+### Compatability
+
+Manners 0.3.0 and above uses standard library functionality introduced in Go 1.3.
+
+### Installation
+
+`go get github.com/braintree/manners`
diff --git a/Godeps/_workspace/src/github.com/go-gorp/gorp/README.md b/Godeps/_workspace/src/github.com/go-gorp/gorp/README.md
new file mode 100644
index 000000000..d2de8c2b6
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/go-gorp/gorp/README.md
@@ -0,0 +1,685 @@
+# Go Relational Persistence
+
+[![build status](https://secure.travis-ci.org/go-gorp/gorp.png)](http://travis-ci.org/go-gorp/gorp)
+
+I hesitate to call gorp an ORM. Go doesn't really have objects, at least
+not in the classic Smalltalk/Java sense. There goes the "O". gorp doesn't
+know anything about the relationships between your structs (at least not
+yet). So the "R" is questionable too (but I use it in the name because,
+well, it seemed more clever).
+
+The "M" is alive and well. Given some Go structs and a database, gorp
+should remove a fair amount of boilerplate busy-work from your code.
+
+I hope that gorp saves you time, minimizes the drudgery of getting data
+in and out of your database, and helps your code focus on algorithms,
+not infrastructure.
+
+* Bind struct fields to table columns via API or tag
+* Support for embedded structs
+* Support for transactions
+* Forward engineer db schema from structs (great for unit tests)
+* Pre/post insert/update/delete hooks
+* Automatically generate insert/update/delete statements for a struct
+* Automatic binding of auto increment PKs back to struct after insert
+* Delete by primary key(s)
+* Select by primary key(s)
+* Optional trace sql logging
+* Bind arbitrary SQL queries to a struct
+* Bind slice to SELECT query results without type assertions
+* Use positional or named bind parameters in custom SELECT queries
+* Optional optimistic locking using a version column (for update/deletes)
+
+## Installation
+
+ # install the library:
+ go get gopkg.in/gorp.v1
+
+ // use in your .go code:
+ import (
+ "gopkg.in/gorp.v1"
+ )
+
+## Versioning
+
+This project provides a stable release (v1.x tags) and a bleeding edge codebase (master).
+
+`gopkg.in/gorp.v1` points to the latest v1.x tag. The API's for v1 are stable and shouldn't change. Development takes place at the master branch. Althought the code in master should always compile and test successfully, it might break API's. We aim to maintain backwards compatibility, but API's and behaviour might be changed to fix a bug. Also note that API's that are new in the master branch can change until released as v2.
+
+If you want to use bleeding edge, use `github.com/go-gorp/gorp` as import path.
+
+## API Documentation
+
+Full godoc output from the latest v1 release is available here:
+
+https://godoc.org/gopkg.in/gorp.v1
+
+For the latest code in master:
+
+https://godoc.org/github.com/go-gorp/gorp
+
+## Supported Go versions
+
+This package is compatible with the last 2 major versions of Go, at this time `1.3` and `1.4`.
+
+Any earlier versions are only supported on a best effort basis and can be dropped any time.
+Go has a great compatibility promise. Upgrading your program to a newer version of Go should never really be a problem.
+
+## Quickstart
+
+```go
+package main
+
+import (
+ "database/sql"
+ "gopkg.in/gorp.v1"
+ _ "github.com/mattn/go-sqlite3"
+ "log"
+ "time"
+)
+
+func main() {
+ // initialize the DbMap
+ dbmap := initDb()
+ defer dbmap.Db.Close()
+
+ // delete any existing rows
+ err := dbmap.TruncateTables()
+ checkErr(err, "TruncateTables failed")
+
+ // create two posts
+ p1 := newPost("Go 1.1 released!", "Lorem ipsum lorem ipsum")
+ p2 := newPost("Go 1.2 released!", "Lorem ipsum lorem ipsum")
+
+ // insert rows - auto increment PKs will be set properly after the insert
+ err = dbmap.Insert(&p1, &p2)
+ checkErr(err, "Insert failed")
+
+ // use convenience SelectInt
+ count, err := dbmap.SelectInt("select count(*) from posts")
+ checkErr(err, "select count(*) failed")
+ log.Println("Rows after inserting:", count)
+
+ // update a row
+ p2.Title = "Go 1.2 is better than ever"
+ count, err = dbmap.Update(&p2)
+ checkErr(err, "Update failed")
+ log.Println("Rows updated:", count)
+
+ // fetch one row - note use of "post_id" instead of "Id" since column is aliased
+ //
+ // Postgres users should use $1 instead of ? placeholders
+ // See 'Known Issues' below
+ //
+ err = dbmap.SelectOne(&p2, "select * from posts where post_id=?", p2.Id)
+ checkErr(err, "SelectOne failed")
+ log.Println("p2 row:", p2)
+
+ // fetch all rows
+ var posts []Post
+ _, err = dbmap.Select(&posts, "select * from posts order by post_id")
+ checkErr(err, "Select failed")
+ log.Println("All rows:")
+ for x, p := range posts {
+ log.Printf(" %d: %v\n", x, p)
+ }
+
+ // delete row by PK
+ count, err = dbmap.Delete(&p1)
+ checkErr(err, "Delete failed")
+ log.Println("Rows deleted:", count)
+
+ // delete row manually via Exec
+ _, err = dbmap.Exec("delete from posts where post_id=?", p2.Id)
+ checkErr(err, "Exec failed")
+
+ // confirm count is zero
+ count, err = dbmap.SelectInt("select count(*) from posts")
+ checkErr(err, "select count(*) failed")
+ log.Println("Row count - should be zero:", count)
+
+ log.Println("Done!")
+}
+
+type Post struct {
+ // db tag lets you specify the column name if it differs from the struct field
+ Id int64 `db:"post_id"`
+ Created int64
+ Title string
+ Body string
+}
+
+func newPost(title, body string) Post {
+ return Post{
+ Created: time.Now().UnixNano(),
+ Title: title,
+ Body: body,
+ }
+}
+
+func initDb() *gorp.DbMap {
+ // connect to db using standard Go database/sql API
+ // use whatever database/sql driver you wish
+ db, err := sql.Open("sqlite3", "/tmp/post_db.bin")
+ checkErr(err, "sql.Open failed")
+
+ // construct a gorp DbMap
+ dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
+
+ // add a table, setting the table name to 'posts' and
+ // specifying that the Id property is an auto incrementing PK
+ dbmap.AddTableWithName(Post{}, "posts").SetKeys(true, "Id")
+
+ // create the table. in a production system you'd generally
+ // use a migration tool, or create the tables via scripts
+ err = dbmap.CreateTablesIfNotExists()
+ checkErr(err, "Create tables failed")
+
+ return dbmap
+}
+
+func checkErr(err error, msg string) {
+ if err != nil {
+ log.Fatalln(msg, err)
+ }
+}
+```
+
+## Examples
+
+### Mapping structs to tables
+
+First define some types:
+
+```go
+type Invoice struct {
+ Id int64
+ Created int64
+ Updated int64
+ Memo string
+ PersonId int64
+}
+
+type Person struct {
+ Id int64
+ Created int64
+ Updated int64
+ FName string
+ LName string
+}
+
+// Example of using tags to alias fields to column names
+// The 'db' value is the column name
+//
+// A hyphen will cause gorp to skip this field, similar to the
+// Go json package.
+//
+// This is equivalent to using the ColMap methods:
+//
+// table := dbmap.AddTableWithName(Product{}, "product")
+// table.ColMap("Id").Rename("product_id")
+// table.ColMap("Price").Rename("unit_price")
+// table.ColMap("IgnoreMe").SetTransient(true)
+//
+type Product struct {
+ Id int64 `db:"product_id"`
+ Price int64 `db:"unit_price"`
+ IgnoreMe string `db:"-"`
+}
+```
+
+Then create a mapper, typically you'd do this one time at app startup:
+
+```go
+// connect to db using standard Go database/sql API
+// use whatever database/sql driver you wish
+db, err := sql.Open("mymysql", "tcp:localhost:3306*mydb/myuser/mypassword")
+
+// construct a gorp DbMap
+dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}
+
+// register the structs you wish to use with gorp
+// you can also use the shorter dbmap.AddTable() if you
+// don't want to override the table name
+//
+// SetKeys(true) means we have a auto increment primary key, which
+// will get automatically bound to your struct post-insert
+//
+t1 := dbmap.AddTableWithName(Invoice{}, "invoice_test").SetKeys(true, "Id")
+t2 := dbmap.AddTableWithName(Person{}, "person_test").SetKeys(true, "Id")
+t3 := dbmap.AddTableWithName(Product{}, "product_test").SetKeys(true, "Id")
+```
+
+### Struct Embedding
+
+gorp supports embedding structs. For example:
+
+```go
+type Names struct {
+ FirstName string
+ LastName string
+}
+
+type WithEmbeddedStruct struct {
+ Id int64
+ Names
+}
+
+es := &WithEmbeddedStruct{-1, Names{FirstName: "Alice", LastName: "Smith"}}
+err := dbmap.Insert(es)
+```
+
+See the `TestWithEmbeddedStruct` function in `gorp_test.go` for a full example.
+
+### Create/Drop Tables ###
+
+Automatically create / drop registered tables. This is useful for unit tests
+but is entirely optional. You can of course use gorp with tables created manually,
+or with a separate migration tool (like [goose](https://bitbucket.org/liamstask/goose) or [migrate](https://github.com/mattes/migrate)).
+
+```go
+// create all registered tables
+dbmap.CreateTables()
+
+// same as above, but uses "if not exists" clause to skip tables that are
+// already defined
+dbmap.CreateTablesIfNotExists()
+
+// drop
+dbmap.DropTables()
+```
+
+### SQL Logging
+
+Optionally you can pass in a logger to trace all SQL statements.
+I recommend enabling this initially while you're getting the feel for what
+gorp is doing on your behalf.
+
+Gorp defines a `GorpLogger` interface that Go's built in `log.Logger` satisfies.
+However, you can write your own `GorpLogger` implementation, or use a package such
+as `glog` if you want more control over how statements are logged.
+
+```go
+// Will log all SQL statements + args as they are run
+// The first arg is a string prefix to prepend to all log messages
+dbmap.TraceOn("[gorp]", log.New(os.Stdout, "myapp:", log.Lmicroseconds))
+
+// Turn off tracing
+dbmap.TraceOff()
+```
+
+### Insert
+
+```go
+// Must declare as pointers so optional callback hooks
+// can operate on your data, not copies
+inv1 := &Invoice{0, 100, 200, "first order", 0}
+inv2 := &Invoice{0, 100, 200, "second order", 0}
+
+// Insert your rows
+err := dbmap.Insert(inv1, inv2)
+
+// Because we called SetKeys(true) on Invoice, the Id field
+// will be populated after the Insert() automatically
+fmt.Printf("inv1.Id=%d inv2.Id=%d\n", inv1.Id, inv2.Id)
+```
+
+### Update
+
+Continuing the above example, use the `Update` method to modify an Invoice:
+
+```go
+// count is the # of rows updated, which should be 1 in this example
+count, err := dbmap.Update(inv1)
+```
+
+### Delete
+
+If you have primary key(s) defined for a struct, you can use the `Delete`
+method to remove rows:
+
+```go
+count, err := dbmap.Delete(inv1)
+```
+
+### Select by Key
+
+Use the `Get` method to fetch a single row by primary key. It returns
+nil if no row is found.
+
+```go
+// fetch Invoice with Id=99
+obj, err := dbmap.Get(Invoice{}, 99)
+inv := obj.(*Invoice)
+```
+
+### Ad Hoc SQL
+
+#### SELECT
+
+`Select()` and `SelectOne()` provide a simple way to bind arbitrary queries to a slice
+or a single struct.
+
+```go
+// Select a slice - first return value is not needed when a slice pointer is passed to Select()
+var posts []Post
+_, err := dbmap.Select(&posts, "select * from post order by id")
+
+// You can also use primitive types
+var ids []string
+_, err := dbmap.Select(&ids, "select id from post")
+
+// Select a single row.
+// Returns an error if no row found, or if more than one row is found
+var post Post
+err := dbmap.SelectOne(&post, "select * from post where id=?", id)
+```
+
+Want to do joins? Just write the SQL and the struct. gorp will bind them:
+
+```go
+// Define a type for your join
+// It *must* contain all the columns in your SELECT statement
+//
+// The names here should match the aliased column names you specify
+// in your SQL - no additional binding work required. simple.
+//
+type InvoicePersonView struct {
+ InvoiceId int64
+ PersonId int64
+ Memo string
+ FName string
+}
+
+// Create some rows
+p1 := &Person{0, 0, 0, "bob", "smith"}
+dbmap.Insert(p1)
+
+// notice how we can wire up p1.Id to the invoice easily
+inv1 := &Invoice{0, 0, 0, "xmas order", p1.Id}
+dbmap.Insert(inv1)
+
+// Run your query
+query := "select i.Id InvoiceId, p.Id PersonId, i.Memo, p.FName " +
+ "from invoice_test i, person_test p " +
+ "where i.PersonId = p.Id"
+
+// pass a slice to Select()
+var list []InvoicePersonView
+_, err := dbmap.Select(&list, query)
+
+// this should test true
+expected := InvoicePersonView{inv1.Id, p1.Id, inv1.Memo, p1.FName}
+if reflect.DeepEqual(list[0], expected) {
+ fmt.Println("Woot! My join worked!")
+}
+```
+
+#### SELECT string or int64
+
+gorp provides a few convenience methods for selecting a single string or int64.
+
+```go
+// select single int64 from db (use $1 instead of ? for postgresql)
+i64, err := dbmap.SelectInt("select count(*) from foo where blah=?", blahVal)
+
+// select single string from db:
+s, err := dbmap.SelectStr("select name from foo where blah=?", blahVal)
+
+```
+
+#### Named bind parameters
+
+You may use a map or struct to bind parameters by name. This is currently
+only supported in SELECT queries.
+
+```go
+_, err := dbm.Select(&dest, "select * from Foo where name = :name and age = :age", map[string]interface{}{
+ "name": "Rob",
+ "age": 31,
+})
+```
+
+#### UPDATE / DELETE
+
+You can execute raw SQL if you wish. Particularly good for batch operations.
+
+```go
+res, err := dbmap.Exec("delete from invoice_test where PersonId=?", 10)
+```
+
+### Transactions
+
+You can batch operations into a transaction:
+
+```go
+func InsertInv(dbmap *DbMap, inv *Invoice, per *Person) error {
+ // Start a new transaction
+ trans, err := dbmap.Begin()
+ if err != nil {
+ return err
+ }
+
+ trans.Insert(per)
+ inv.PersonId = per.Id
+ trans.Insert(inv)
+
+ // if the commit is successful, a nil error is returned
+ return trans.Commit()
+}
+```
+
+### Hooks
+
+Use hooks to update data before/after saving to the db. Good for timestamps:
+
+```go
+// implement the PreInsert and PreUpdate hooks
+func (i *Invoice) PreInsert(s gorp.SqlExecutor) error {
+ i.Created = time.Now().UnixNano()
+ i.Updated = i.Created
+ return nil
+}
+
+func (i *Invoice) PreUpdate(s gorp.SqlExecutor) error {
+ i.Updated = time.Now().UnixNano()
+ return nil
+}
+
+// You can use the SqlExecutor to cascade additional SQL
+// Take care to avoid cycles. gorp won't prevent them.
+//
+// Here's an example of a cascading delete
+//
+func (p *Person) PreDelete(s gorp.SqlExecutor) error {
+ query := "delete from invoice_test where PersonId=?"
+ err := s.Exec(query, p.Id); if err != nil {
+ return err
+ }
+ return nil
+}
+```
+
+Full list of hooks that you can implement:
+
+ PostGet
+ PreInsert
+ PostInsert
+ PreUpdate
+ PostUpdate
+ PreDelete
+ PostDelete
+
+ All have the same signature. for example:
+
+ func (p *MyStruct) PostUpdate(s gorp.SqlExecutor) error
+
+### Optimistic Locking
+
+#### Note that this behaviour has changed in v2. See [Migration Guide](#migration-guide).
+
+gorp provides a simple optimistic locking feature, similar to Java's JPA, that
+will raise an error if you try to update/delete a row whose `version` column
+has a value different than the one in memory. This provides a safe way to do
+"select then update" style operations without explicit read and write locks.
+
+```go
+// Version is an auto-incremented number, managed by gorp
+// If this property is present on your struct, update
+// operations will be constrained
+//
+// For example, say we defined Person as:
+
+type Person struct {
+ Id int64
+ Created int64
+ Updated int64
+ FName string
+ LName string
+
+ // automatically used as the Version col
+ // use table.SetVersionCol("columnName") to map a different
+ // struct field as the version field
+ Version int64
+}
+
+p1 := &Person{0, 0, 0, "Bob", "Smith", 0}
+dbmap.Insert(p1) // Version is now 1
+
+obj, err := dbmap.Get(Person{}, p1.Id)
+p2 := obj.(*Person)
+p2.LName = "Edwards"
+dbmap.Update(p2) // Version is now 2
+
+p1.LName = "Howard"
+
+// Raises error because p1.Version == 1, which is out of date
+count, err := dbmap.Update(p1)
+_, ok := err.(gorp.OptimisticLockError)
+if ok {
+ // should reach this statement
+
+ // in a real app you might reload the row and retry, or
+ // you might propegate this to the user, depending on the desired
+ // semantics
+ fmt.Printf("Tried to update row with stale data: %v\n", err)
+} else {
+ // some other db error occurred - log or return up the stack
+ fmt.Printf("Unknown db err: %v\n", err)
+}
+```
+
+## Database Drivers
+
+gorp uses the Go 1 `database/sql` package. A full list of compliant drivers is available here:
+
+http://code.google.com/p/go-wiki/wiki/SQLDrivers
+
+Sadly, SQL databases differ on various issues. gorp provides a Dialect interface that should be
+implemented per database vendor. Dialects are provided for:
+
+* MySQL
+* PostgreSQL
+* sqlite3
+
+Each of these three databases pass the test suite. See `gorp_test.go` for example
+DSNs for these three databases.
+
+Support is also provided for:
+
+* Oracle (contributed by @klaidliadon)
+* SQL Server (contributed by @qrawl) - use driver: github.com/denisenkom/go-mssqldb
+
+Note that these databases are not covered by CI and I (@coopernurse) have no good way to
+test them locally. So please try them and send patches as needed, but expect a bit more
+unpredicability.
+
+## Known Issues
+
+### SQL placeholder portability
+
+Different databases use different strings to indicate variable placeholders in
+prepared SQL statements. Unlike some database abstraction layers (such as JDBC),
+Go's `database/sql` does not standardize this.
+
+SQL generated by gorp in the `Insert`, `Update`, `Delete`, and `Get` methods delegates
+to a Dialect implementation for each database, and will generate portable SQL.
+
+Raw SQL strings passed to `Exec`, `Select`, `SelectOne`, `SelectInt`, etc will not be
+parsed. Consequently you may have portability issues if you write a query like this:
+
+```go
+// works on MySQL and Sqlite3, but not with Postgresql
+err := dbmap.SelectOne(&val, "select * from foo where id = ?", 30)
+```
+
+In `Select` and `SelectOne` you can use named parameters to work around this.
+The following is portable:
+
+```go
+err := dbmap.SelectOne(&val, "select * from foo where id = :id",
+ map[string]interface{} { "id": 30})
+```
+
+### time.Time and time zones
+
+gorp will pass `time.Time` fields through to the `database/sql` driver, but note that
+the behavior of this type varies across database drivers.
+
+MySQL users should be especially cautious. See: https://github.com/ziutek/mymysql/pull/77
+
+To avoid any potential issues with timezone/DST, consider using an integer field for time
+data and storing UNIX time.
+
+## Running the tests
+
+The included tests may be run against MySQL, Postgresql, or sqlite3.
+You must set two environment variables so the test code knows which driver to
+use, and how to connect to your database.
+
+```sh
+# MySQL example:
+export GORP_TEST_DSN=gomysql_test/gomysql_test/abc123
+export GORP_TEST_DIALECT=mysql
+
+# run the tests
+go test
+
+# run the tests and benchmarks
+go test -bench="Bench" -benchtime 10
+```
+
+Valid `GORP_TEST_DIALECT` values are: "mysql"(for mymysql), "gomysql"(for go-sql-driver), "postgres", "sqlite"
+See the `test_all.sh` script for examples of all 3 databases. This is the script I run
+locally to test the library.
+
+## Performance
+
+gorp uses reflection to construct SQL queries and bind parameters. See the BenchmarkNativeCrud vs BenchmarkGorpCrud in gorp_test.go for a simple perf test. On my MacBook Pro gorp is about 2-3% slower than hand written SQL.
+
+## Migration guide
+#### Pre-v2 to v2
+Automatic mapping of the version column used in optimistic locking has been removed as it could cause problems if the type was not int. The version column must now explicitly be set with tablemap.SetVersionCol().
+
+## Help/Support
+
+IRC: #gorp
+Mailing list: gorp-dev@googlegroups.com
+Bugs/Enhancements: Create a github issue
+
+## Pull requests / Contributions
+
+Contributions are very welcome. Please follow these guidelines:
+
+* Fork the `master` branch and issue pull requests targeting the `master` branch
+* If you are adding an enhancement, please open an issue first with your proposed change.
+* Changes that break backwards compatibility in the public API are only accepted after we
+ discuss on a GitHub issue for a while.
+
+Thanks!
+
+## Contributors
+
+* matthias-margush - column aliasing via tags
+* Rob Figueiredo - @robfig
+* Quinn Slack - @sqs
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md
new file mode 100644
index 000000000..9edb7628b
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/README.md
@@ -0,0 +1,376 @@
+# Go-MySQL-Driver
+
+A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) package
+
+![Go-MySQL-Driver logo](https://raw.github.com/wiki/go-sql-driver/mysql/gomysql_m.png "Golang Gopher holding the MySQL Dolphin")
+
+**Latest stable Release:** [Version 1.2 (June 03, 2014)](https://github.com/go-sql-driver/mysql/releases)
+
+[![Build Status](https://travis-ci.org/go-sql-driver/mysql.png?branch=master)](https://travis-ci.org/go-sql-driver/mysql)
+
+---------------------------------------
+ * [Features](#features)
+ * [Requirements](#requirements)
+ * [Installation](#installation)
+ * [Usage](#usage)
+ * [DSN (Data Source Name)](#dsn-data-source-name)
+ * [Password](#password)
+ * [Protocol](#protocol)
+ * [Address](#address)
+ * [Parameters](#parameters)
+ * [Examples](#examples)
+ * [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
+ * [time.Time support](#timetime-support)
+ * [Unicode support](#unicode-support)
+ * [Testing / Development](#testing--development)
+ * [License](#license)
+
+---------------------------------------
+
+## Features
+ * Lightweight and [fast](https://github.com/go-sql-driver/sql-benchmark "golang MySQL-Driver performance")
+ * Native Go implementation. No C-bindings, just pure Go
+ * Connections over TCP/IPv4, TCP/IPv6 or Unix domain sockets
+ * Automatic handling of broken connections
+ * Automatic Connection Pooling *(by database/sql package)*
+ * Supports queries larger than 16MB
+ * Full [`sql.RawBytes`](http://golang.org/pkg/database/sql/#RawBytes) support.
+ * Intelligent `LONG DATA` handling in prepared statements
+ * Secure `LOAD DATA LOCAL INFILE` support with file Whitelisting and `io.Reader` support
+ * Optional `time.Time` parsing
+ * Optional placeholder interpolation
+
+## Requirements
+ * Go 1.2 or higher
+ * MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
+
+---------------------------------------
+
+## Installation
+Simple install the package to your [$GOPATH](http://code.google.com/p/go-wiki/wiki/GOPATH "GOPATH") with the [go tool](http://golang.org/cmd/go/ "go command") from shell:
+```bash
+$ go get github.com/go-sql-driver/mysql
+```
+Make sure [Git is installed](http://git-scm.com/downloads) on your machine and in your system's `PATH`.
+
+## Usage
+_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](http://golang.org/pkg/database/sql) API then.
+
+Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`:
+```go
+import "database/sql"
+import _ "github.com/go-sql-driver/mysql"
+
+db, err := sql.Open("mysql", "user:password@/dbname")
+```
+
+[Examples are available in our Wiki](https://github.com/go-sql-driver/mysql/wiki/Examples "Go-MySQL-Driver Examples").
+
+
+### DSN (Data Source Name)
+
+The Data Source Name has a common format, like e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php) uses it, but without type-prefix (optional parts marked by squared brackets):
+```
+[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
+```
+
+A DSN in its fullest form:
+```
+username:password@protocol(address)/dbname?param=value
+```
+
+Except for the databasename, all values are optional. So the minimal DSN is:
+```
+/dbname
+```
+
+If you do not want to preselect a database, leave `dbname` empty:
+```
+/
+```
+This has the same effect as an empty DSN string:
+```
+
+```
+
+#### Password
+Passwords can consist of any character. Escaping is **not** necessary.
+
+#### Protocol
+See [net.Dial](http://golang.org/pkg/net/#Dial) for more information which networks are available.
+In general you should use an Unix domain socket if available and TCP otherwise for best performance.
+
+#### Address
+For TCP and UDP networks, addresses have the form `host:port`.
+If `host` is a literal IPv6 address, it must be enclosed in square brackets.
+The functions [net.JoinHostPort](http://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](http://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form.
+
+For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. `/var/run/mysqld/mysqld.sock` or `/tmp/mysql.sock`.
+
+#### Parameters
+*Parameters are case-sensitive!*
+
+Notice that any of `true`, `TRUE`, `True` or `1` is accepted to stand for a true boolean value. Not surprisingly, false can be specified as any of: `false`, `FALSE`, `False` or `0`.
+
+##### `allowAllFiles`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`allowAllFiles=true` disables the file Whitelist for `LOAD DATA LOCAL INFILE` and allows *all* files.
+[*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)
+
+##### `allowOldPasswords`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+`allowOldPasswords=true` allows the usage of the insecure old password method. This should be avoided, but is necessary in some cases. See also [the old_passwords wiki page](https://github.com/go-sql-driver/mysql/wiki/old_passwords).
+
+##### `charset`
+
+```
+Type: string
+Valid Values: <name>
+Default: none
+```
+
+Sets the charset used for client-server interaction (`"SET NAMES <value>"`). If multiple charsets are set (separated by a comma), the following charset is used if setting the charset failes. This enables for example support for `utf8mb4` ([introduced in MySQL 5.5.3](http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html)) with fallback to `utf8` for older servers (`charset=utf8mb4,utf8`).
+
+Usage of the `charset` parameter is discouraged because it issues additional queries to the server.
+Unless you need the fallback behavior, please use `collation` instead.
+
+##### `collation`
+
+```
+Type: string
+Valid Values: <name>
+Default: utf8_general_ci
+```
+
+Sets the collation used for client-server interaction on connection. In contrast to `charset`, `collation` does not issue additional queries. If the specified collation is unavailable on the target server, the connection will fail.
+
+A list of valid charsets for a server is retrievable with `SHOW COLLATION`.
+
+##### `clientFoundRows`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`clientFoundRows=true` causes an UPDATE to return the number of matching rows instead of the number of rows changed.
+
+##### `columnsWithAlias`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+When `columnsWithAlias` is true, calls to `sql.Rows.Columns()` will return the table alias and the column name separated by a dot. For example:
+
+```
+SELECT u.id FROM users as u
+```
+
+will return `u.id` instead of just `id` if `columnsWithAlias=true`.
+
+##### `interpolateParams`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+If `interpolateParams` is true, placeholders (`?`) in calls to `db.Query()` and `db.Exec()` are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with `interpolateParams=false`.
+
+*This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are blacklisted as they may [introduce a SQL injection vulnerability](http://stackoverflow.com/a/12118602/3430118)!*
+
+##### `loc`
+
+```
+Type: string
+Valid Values: <escaped name>
+Default: UTC
+```
+
+Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](http://golang.org/pkg/time/#LoadLocation) for details.
+
+Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter.
+
+Please keep in mind, that param values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
+
+
+##### `parseTime`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string`
+
+
+##### `strict`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+
+`strict=true` enables the strict mode in which MySQL warnings are treated as errors.
+
+By default MySQL also treats notes as warnings. Use [`sql_notes=false`](http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_sql_notes) to ignore notes. See the [examples](#examples) for an DSN example.
+
+
+##### `timeout`
+
+```
+Type: decimal number
+Default: OS default
+```
+
+*Driver* side connection timeout. The value must be a string of decimal numbers, each with optional fraction and a unit suffix ( *"ms"*, *"s"*, *"m"*, *"h"* ), such as *"30s"*, *"0.5m"* or *"1m30s"*. To set a server side timeout, use the parameter [`wait_timeout`](http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout).
+
+
+##### `tls`
+
+```
+Type: bool / string
+Valid Values: true, false, skip-verify, <name>
+Default: false
+```
+
+`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](http://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
+
+
+##### System Variables
+
+All other parameters are interpreted as system variables:
+ * `autocommit`: `"SET autocommit=<value>"`
+ * [`time_zone`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `"SET time_zone=<value>"`
+ * [`tx_isolation`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `"SET tx_isolation=<value>"`
+ * `param`: `"SET <param>=<value>"`
+
+*The values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!*
+
+#### Examples
+```
+user@unix(/path/to/socket)/dbname
+```
+
+```
+root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local
+```
+
+```
+user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true
+```
+
+Use the [strict mode](#strict) but ignore notes:
+```
+user:password@/dbname?strict=true&sql_notes=false
+```
+
+TCP via IPv6:
+```
+user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci
+```
+
+TCP on a remote host, e.g. Amazon RDS:
+```
+id:password@tcp(your-amazonaws-uri.com:3306)/dbname
+```
+
+Google Cloud SQL on App Engine:
+```
+user@cloudsql(project-id:instance-name)/dbname
+```
+
+TCP using default port (3306) on localhost:
+```
+user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped
+```
+
+Use the default protocol (tcp) and host (localhost:3306):
+```
+user:password@/dbname
+```
+
+No Database preselected:
+```
+user:password@/
+```
+
+### `LOAD DATA LOCAL INFILE` support
+For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
+```go
+import "github.com/go-sql-driver/mysql"
+```
+
+Files must be whitelisted by registering them with `mysql.RegisterLocalFile(filepath)` (recommended) or the Whitelist check must be deactivated by using the DSN parameter `allowAllFiles=true` ([*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)).
+
+To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::<name>` then.
+
+See the [godoc of Go-MySQL-Driver](http://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.
+
+
+### `time.Time` support
+The default internal output type of MySQL `DATE` and `DATETIME` values is `[]byte` which allows you to scan the value into a `[]byte`, `string` or `sql.RawBytes` variable in your programm.
+
+However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](http://golang.org/pkg/time/#Location) with the `loc` DSN parameter.
+
+**Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes).
+
+Alternatively you can use the [`NullTime`](http://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`.
+
+
+### Unicode support
+Since version 1.1 Go-MySQL-Driver automatically uses the collation `utf8_general_ci` by default.
+
+Other collations / charsets can be set using the [`collation`](#collation) DSN parameter.
+
+Version 1.0 of the driver recommended adding `&charset=utf8` (alias for `SET NAMES utf8`) to the DSN to enable proper UTF-8 support. This is not necessary anymore. The [`collation`](#collation) parameter should be preferred to set another collation / charset than the default.
+
+See http://dev.mysql.com/doc/refman/5.7/en/charset-unicode.html for more details on MySQL's Unicode support.
+
+
+## Testing / Development
+To run the driver tests you may need to adjust the configuration. See the [Testing Wiki-Page](https://github.com/go-sql-driver/mysql/wiki/Testing "Testing") for details.
+
+Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated.
+If you want to contribute, you can work on an [open issue](https://github.com/go-sql-driver/mysql/issues?state=open) or review a [pull request](https://github.com/go-sql-driver/mysql/pulls).
+
+See the [Contribution Guidelines](https://github.com/go-sql-driver/mysql/blob/master/CONTRIBUTING.md) for details.
+
+---------------------------------------
+
+## License
+Go-MySQL-Driver is licensed under the [Mozilla Public License Version 2.0](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
+
+Mozilla summarizes the license scope as follows:
+> MPL: The copyleft applies to any files containing MPLed code.
+
+
+That means:
+ * You can **use** the **unchanged** source code both in private and commercially
+ * When distributing, you **must publish** the source code of any **changed files** licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0)
+ * You **needn't publish** the source code of your library as long as the files licensed under the MPL 2.0 are **unchanged**
+
+Please read the [MPL 2.0 FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html) if you have further questions regarding the license.
+
+You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
+
+![Go Gopher and MySQL Dolphin](https://raw.github.com/wiki/go-sql-driver/mysql/go-mysql-driver_m.jpg "Golang Gopher transporting the MySQL Dolphin in a wheelbarrow")
+
diff --git a/Godeps/_workspace/src/github.com/gorilla/context/README.md b/Godeps/_workspace/src/github.com/gorilla/context/README.md
new file mode 100644
index 000000000..c60a31b05
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/context/README.md
@@ -0,0 +1,7 @@
+context
+=======
+[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context)
+
+gorilla/context is a general purpose registry for global request variables.
+
+Read the full documentation here: http://www.gorillatoolkit.org/pkg/context
diff --git a/Godeps/_workspace/src/github.com/gorilla/mux/README.md b/Godeps/_workspace/src/github.com/gorilla/mux/README.md
new file mode 100644
index 000000000..e60301b03
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/mux/README.md
@@ -0,0 +1,7 @@
+mux
+===
+[![Build Status](https://travis-ci.org/gorilla/mux.png?branch=master)](https://travis-ci.org/gorilla/mux)
+
+gorilla/mux is a powerful URL router and dispatcher.
+
+Read the full documentation here: http://www.gorillatoolkit.org/pkg/mux
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/README.md
new file mode 100644
index 000000000..9ad75a0f5
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/README.md
@@ -0,0 +1,59 @@
+# Gorilla WebSocket
+
+Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
+[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
+
+### Documentation
+
+* [API Reference](http://godoc.org/github.com/gorilla/websocket)
+* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
+* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)
+
+### Status
+
+The Gorilla WebSocket package provides a complete and tested implementation of
+the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
+package API is stable.
+
+### Installation
+
+ go get github.com/gorilla/websocket
+
+### Protocol Compliance
+
+The Gorilla WebSocket package passes the server tests in the [Autobahn Test
+Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
+subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
+
+### Gorilla WebSocket compared with other packages
+
+<table>
+<tr>
+<th></th>
+<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
+<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
+</tr>
+<tr>
+<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
+<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
+<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
+<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
+<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
+<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
+<tr><td colspan="3">Other Features</tr></td>
+<tr><td>Limit size of received message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.SetReadLimit">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=5082">No</a></td></tr>
+<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
+<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
+</table>
+
+Notes:
+
+1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
+2. The application can get the type of a received data message by implementing
+ a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
+ function.
+3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
+ Read returns when the input buffer is full or a frame boundary is
+ encountered. Each call to Write sends a single frame message. The Gorilla
+ io.Reader and io.WriteCloser operate on a single WebSocket message.
+
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md
new file mode 100644
index 000000000..075ac1530
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/autobahn/README.md
@@ -0,0 +1,13 @@
+# Test Server
+
+This package contains a server for the [Autobahn WebSockets Test Suite](http://autobahn.ws/testsuite).
+
+To test the server, run
+
+ go run server.go
+
+and start the client test driver
+
+ wstest -m fuzzingclient -s fuzzingclient.json
+
+When the client completes, it writes a report to reports/clients/index.html.
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
new file mode 100644
index 000000000..08fc3e65c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/chat/README.md
@@ -0,0 +1,19 @@
+# Chat Example
+
+This application shows how to use use the
+[websocket](https://github.com/gorilla/websocket) package and
+[jQuery](http://jquery.com) to implement a simple web chat application.
+
+## Running the example
+
+The example requires a working Go development environment. The [Getting
+Started](http://golang.org/doc/install) page describes how to install the
+development environment.
+
+Once you have Go up and running, you can download, build and run the example
+using the following commands.
+
+ $ go get github.com/gorilla/websocket
+ $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/chat`
+ $ go run *.go
+
diff --git a/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md
new file mode 100644
index 000000000..ca4931f3b
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/gorilla/websocket/examples/filewatch/README.md
@@ -0,0 +1,9 @@
+# File Watch example.
+
+This example sends a file to the browser client for display whenever the file is modified.
+
+ $ go get github.com/gorilla/websocket
+ $ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/filewatch`
+ $ go run main.go <name of file to watch>
+ # Open http://localhost:8080/ .
+ # Modify the file to see it update in the browser.
diff --git a/Godeps/_workspace/src/github.com/huandu/facebook/README.md b/Godeps/_workspace/src/github.com/huandu/facebook/README.md
new file mode 100644
index 000000000..a21de8d7c
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/huandu/facebook/README.md
@@ -0,0 +1,347 @@
+# A Facebook Graph API SDK In Golang #
+
+[![Build Status](https://travis-ci.org/huandu/facebook.png?branch=master)](https://travis-ci.org/huandu/facebook)
+
+This is a Go package fully supports Facebook Graph API with file upload, batch request, FQL and multi-FQL. It can be used in Google App Engine.
+
+API documents can be found on [godoc](http://godoc.org/github.com/huandu/facebook).
+
+Feel free to create an issue or send me a pull request if you have any "how-to" question or bug or suggestion when using this package. I'll try my best to reply it.
+
+## Get It ##
+
+Use `go get -u github.com/huandu/facebook` to get or update it.
+
+## Usage ##
+
+### Quick start ###
+
+Here is a sample to read my Facebook username by uid.
+
+```go
+package main
+
+import (
+ "fmt"
+ fb "github.com/huandu/facebook"
+)
+
+func main() {
+ res, _ := fb.Get("/538744468", fb.Params{
+ "fields": "username",
+ "access_token": "a-valid-access-token",
+ })
+ fmt.Println("here is my facebook username:", res["username"])
+}
+```
+
+Type of `res` is `fb.Result` (a.k.a. `map[string]interface{}`).
+This type has several useful methods to decode `res` to any Go type safely.
+
+```go
+// Decode "username" to a Go string.
+var username string
+res.DecodeField("username", &username)
+fmt.Println("alternative way to get username:", username)
+
+// It's also possible to decode the whole result into a predefined struct.
+type User struct {
+ Username string
+}
+
+var user User
+res.Decode(&user)
+fmt.Println("print username in struct:", user.Username)
+```
+
+### Read a graph `user` object with a valid access token ###
+
+```go
+res, err := fb.Get("/me/feed", fb.Params{
+ "access_token": "a-valid-access-token",
+})
+
+if err != nil {
+ // err can be an facebook API error.
+ // if so, the Error struct contains error details.
+ if e, ok := err.(*Error); ok {
+ fmt.Logf("facebook error. [message:%v] [type:%v] [code:%v] [subcode:%v]",
+ e.Message, e.Type, e.Code, e.ErrorSubcode)
+ return
+ }
+
+ return
+}
+
+// read my last feed.
+fmt.Println("my latest feed story is:", res.Get("data.0.story"))
+```
+
+### Read a graph `search` for page and decode slice of maps
+
+```go
+res, _ := fb.Get("/search", fb.Params{
+ "access_token": "a-valid-access-token",
+ "type": "page",
+ "q": "nightlife,singapore",
+ })
+
+var items []fb.Result
+
+err := res.DecodeField("data", &items)
+
+if err != nil {
+ fmt.Logf("An error has happened %v", err)
+ return
+}
+
+for _, item := range items {
+ fmt.Println(item["id"])
+}
+```
+
+### Use `App` and `Session` ###
+
+It's recommended to use `App` and `Session` in a production app. They provide more controls over all API calls. They can also make code clear and concise.
+
+```go
+// create a global App var to hold app id and secret.
+var globalApp = fb.New("your-app-id", "your-app-secret")
+
+// facebook asks for a valid redirect uri when parsing signed request.
+// it's a new enforced policy starting in late 2013.
+globalApp.RedirectUri = "http://your.site/canvas/url/"
+
+// here comes a client with a facebook signed request string in query string.
+// creates a new session with signed request.
+session, _ := globalApp.SessionFromSignedRequest(signedRequest)
+
+// if there is another way to get decoded access token,
+// creates a session directly with the token.
+session := globalApp.Session(token)
+
+// validate access token. err is nil if token is valid.
+err := session.Validate()
+
+// use session to send api request with access token.
+res, _ := session.Get("/me/feed", nil)
+```
+
+### Use `paging` field in response. ###
+
+Some Graph API responses use a special JSON structure to provide paging information. Use `Result.Paging()` to walk through all data in such results.
+
+```go
+res, _ := session.Get("/me/home", nil)
+
+// create a paging structure.
+paging, _ := res.Paging(session)
+
+// get current results.
+results := paging.Data()
+
+// get next page.
+noMore, err := paging.Next()
+results = paging.Data()
+```
+
+### Read graph api response and decode result into a struct ###
+
+As facebook Graph API always uses lower case words as keys in API response.
+This package can convert go's camel-case-style struct field name to facebook's underscore-style API key name.
+
+For instance, to decode following JSON response...
+
+```json
+{
+ "foo_bar": "player"
+}
+```
+
+One can use following struct.
+
+```go
+type Data struct {
+ FooBar string // "FooBar" maps to "foo_bar" in JSON automatically in this case.
+}
+```
+
+Decoding behavior can be changed per field through field tag -- just like what `encoding/json` does.
+
+Following is a sample shows all possible field tags.
+
+```go
+// define a facebook feed object.
+type FacebookFeed struct {
+ Id string `facebook:",required"` // this field must exist in response.
+ // mind the "," before "required".
+ Story string
+ FeedFrom *FacebookFeedFrom `facebook:"from"` // use customized field name "from"
+ CreatedTime string `facebook:"created_time,required"` // both customized field name and "required" flag.
+}
+
+type FacebookFeedFrom struct {
+ Name, Id string
+}
+
+// create a feed object direct from graph api result.
+var feed FacebookFeed
+res, _ := session.Get("/me/feed", nil)
+res.DecodeField("data.0", &feed) // read latest feed
+```
+
+### Send a batch request ###
+
+```go
+params1 := Params{
+ "method": fb.GET,
+ "relative_url": "me",
+}
+params2 := Params{
+ "method": fb.GET,
+ "relative_url": uint64(100002828925788),
+}
+results, err := fb.BatchApi(your_access_token, params1, params2)
+
+if err != nil {
+ // check error...
+ return
+}
+
+// batchResult1 and batchResult2 are response for params1 and params2.
+batchResult1, _ := results[0].Batch()
+batchResult2, _ := results[1].Batch()
+
+// Use parsed result.
+var id string
+res := batchResult1.Result
+res.DecodeField("id", &id)
+
+// Use response header.
+contentType := batchResult1.Header.Get("Content-Type")
+```
+
+### Send FQL query ###
+
+```go
+results, _ := fb.FQL("SELECT username FROM page WHERE page_id = 20531316728")
+fmt.Println(results[0]["username"]) // print "facebook"
+
+// most FQL query requires access token. create session to hold access token.
+session := &fb.Session{}
+session.SetAccessToken("A-VALID-ACCESS-TOKEN")
+results, _ := session.FQL("SELECT username FROM page WHERE page_id = 20531316728")
+fmt.Println(results[0]["username"]) // print "facebook"
+```
+
+### Make multi-FQL ###
+
+```go
+res, _ := fb.MultiFQL(Params{
+ "query1": "SELECT username FROM page WHERE page_id = 20531316728",
+ "query2": "SELECT uid FROM user WHERE uid = 538744468",
+})
+var query1, query2 []Result
+
+// get response for query1 and query2.
+res.DecodeField("query1", &query1)
+res.DecodeField("query2", &query2)
+
+// most FQL query requires access token. create session to hold access token.
+session := &fb.Session{}
+session.SetAccessToken("A-VALID-ACCESS-TOKEN")
+res, _ := session.MultiFQL(Params{
+ "query1": "...",
+ "query2": "...",
+})
+
+// same as the sample without access token...
+```
+
+### Use it in Google App Engine ###
+
+Google App Engine provide `appengine/urlfetch` package as standard http client package. Default client in `net/http` doesn't work. One must explicitly set http client in `Session` to make it work.
+
+```go
+import (
+ "appengine"
+ "appengine/urlfetch"
+)
+
+// suppose it's the appengine context initialized somewhere.
+var context appengine.Context
+
+// default Session object uses http.DefaultClient which is not allowed to use
+// in appengine. one has to create a Session and assign it a special client.
+seesion := globalApp.Session("a-access-token")
+session.HttpClient = urlfetch.Client(context)
+
+// now, session uses appengine http client now.
+res, err := session.Get("/me", nil)
+```
+
+### Select Graph API version ###
+
+See [Platform Versioning](https://developers.facebook.com/docs/apps/versions) to understand facebook versioning strategy.
+
+```go
+// this package uses default version which is controlled by facebook app setting.
+// change following global variable to specific a global default version.
+fb.Version = "v2.0"
+
+// starting with graph api v2.0, it's not allowed to get user information without access token.
+fb.Api("huan.du", GET, nil)
+
+// it's possible to specify version per session.
+session := &fb.Session{}
+session.Version = "v2.0" // overwrite global default.
+```
+
+### Enable `appsecret_proof` ###
+
+Facebook can verify Graph API Calls with `appsecret_proof`. It's a feature to make Graph API call more secure. See [Securing Graph API Requests](https://developers.facebook.com/docs/graph-api/securing-requests) to know more about it.
+
+```go
+globalApp := fb.New("your-app-id", "your-app-secret")
+
+// enable "appsecret_proof" for all sessions created by this app.
+globalApp.EnableAppsecretProof = true
+
+// all calls in this session are secured.
+session := globalApp.Session("a-valid-access-token")
+session.Get("/me", nil)
+
+// it's also possible to enable/disable this feature per session.
+session.EnableAppsecretProof(false)
+```
+
+### Debugging API Requests ###
+
+Facebook introduces a way to debug graph API calls. See [Debugging API Requests](https://developers.facebook.com/docs/graph-api/using-graph-api/v2.3#debugging) for details.
+
+This package provides both package level and per session debug flag. Set `Debug` to a `DEBUG_*` constant to change debug mode globally; or use `Session#SetDebug` to change debug mode for one session.
+
+When debug mode is turned on, use `Result#DebugInfo` to get `DebugInfo` struct from result.
+
+```go
+fb.Debug = fb.DEBUG_ALL
+
+res, _ := fb.Get("/me", fb.Params{"access_token": "xxx"})
+debugInfo := res.DebugInfo()
+
+fmt.Println("http headers:", debugInfo.Header)
+fmt.Println("facebook api version:", debugInfo.FacebookApiVersion)
+```
+
+## Change Log ##
+
+See [CHANGELOG.md](CHANGELOG.md).
+
+## Out of Scope ##
+
+1. No OAuth integration. This package only provides APIs to parse/verify access token and code generated in OAuth 2.0 authentication process.
+2. No old RESTful API support. Such APIs are deprecated for years. Forget about them.
+
+## License ##
+
+This package is licensed under MIT license. See LICENSE for details.
diff --git a/Godeps/_workspace/src/github.com/mssola/user_agent/README.md b/Godeps/_workspace/src/github.com/mssola/user_agent/README.md
new file mode 100644
index 000000000..7f0b15aa5
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/mssola/user_agent/README.md
@@ -0,0 +1,51 @@
+
+# UserAgent [![Build Status](https://travis-ci.org/mssola/user_agent.png?branch=master)](https://travis-ci.org/mssola/user_agent) [![GoDoc](https://godoc.org/github.com/mssola/user_agent?status.png)](http://godoc.org/github.com/mssola/user_agent)
+
+
+UserAgent is a Go library that parses HTTP User Agents.
+
+## Usage
+
+~~~ go
+package main
+
+import (
+ "fmt"
+
+ "github.com/mssola/user_agent"
+)
+
+func main() {
+ // The "New" function will create a new UserAgent object and it will parse
+ // the given string. If you need to parse more strings, you can re-use
+ // this object and call: ua.Parse("another string")
+ ua := user_agent.New("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11");
+
+ fmt.Printf("%v\n", ua.Mobile()) // => false
+ fmt.Printf("%v\n", ua.Bot()) // => false
+ fmt.Printf("%v\n", ua.Mozilla()) // => "5.0"
+
+ fmt.Printf("%v\n", ua.Platform()) // => "X11"
+ fmt.Printf("%v\n", ua.OS()) // => "Linux x86_64"
+
+ name, version := ua.Engine()
+ fmt.Printf("%v\n", name) // => "AppleWebKit"
+ fmt.Printf("%v\n", version) // => "537.11"
+
+ name, version = ua.Browser()
+ fmt.Printf("%v\n", name) // => "Chrome"
+ fmt.Printf("%v\n", version) // => "23.0.1271.97"
+
+ // Let's see an example with a bot.
+
+ ua.Parse("Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)")
+
+ fmt.Printf("%v\n", ua.Bot()) // => true
+
+ name, version = ua.Browser()
+ fmt.Printf("%v\n", name) // => Googlebot
+ fmt.Printf("%v\n", version) // => 2.1
+}
+~~~
+
+Copyright &copy; 2012-2015 Miquel Sabaté Solà, released under the MIT License.
diff --git a/Godeps/_workspace/src/github.com/nfnt/resize/README.md b/Godeps/_workspace/src/github.com/nfnt/resize/README.md
new file mode 100644
index 000000000..2aefa75c9
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/nfnt/resize/README.md
@@ -0,0 +1,149 @@
+Resize
+======
+
+Image resizing for the [Go programming language](http://golang.org) with common interpolation methods.
+
+[![Build Status](https://travis-ci.org/nfnt/resize.svg)](https://travis-ci.org/nfnt/resize)
+
+Installation
+------------
+
+```bash
+$ go get github.com/nfnt/resize
+```
+
+It's that easy!
+
+Usage
+-----
+
+This package needs at least Go 1.1. Import package with
+
+```go
+import "github.com/nfnt/resize"
+```
+
+The resize package provides 2 functions:
+
+* `resize.Resize` creates a scaled image with new dimensions (`width`, `height`) using the interpolation function `interp`.
+ If either `width` or `height` is set to 0, it will be set to an aspect ratio preserving value.
+* `resize.Thumbnail` downscales an image preserving its aspect ratio to the maximum dimensions (`maxWidth`, `maxHeight`).
+ It will return the original image if original sizes are smaller than the provided dimensions.
+
+```go
+resize.Resize(width, height uint, img image.Image, interp resize.InterpolationFunction) image.Image
+resize.Thumbnail(maxWidth, maxHeight uint, img image.Image, interp resize.InterpolationFunction) image.Image
+```
+
+The provided interpolation functions are (from fast to slow execution time)
+
+- `NearestNeighbor`: [Nearest-neighbor interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation)
+- `Bilinear`: [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation)
+- `Bicubic`: [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation)
+- `MitchellNetravali`: [Mitchell-Netravali interpolation](http://dl.acm.org/citation.cfm?id=378514)
+- `Lanczos2`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=2
+- `Lanczos3`: [Lanczos resampling](http://en.wikipedia.org/wiki/Lanczos_resampling) with a=3
+
+Which of these methods gives the best results depends on your use case.
+
+Sample usage:
+
+```go
+package main
+
+import (
+ "github.com/nfnt/resize"
+ "image/jpeg"
+ "log"
+ "os"
+)
+
+func main() {
+ // open "test.jpg"
+ file, err := os.Open("test.jpg")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // decode jpeg into image.Image
+ img, err := jpeg.Decode(file)
+ if err != nil {
+ log.Fatal(err)
+ }
+ file.Close()
+
+ // resize to width 1000 using Lanczos resampling
+ // and preserve aspect ratio
+ m := resize.Resize(1000, 0, img, resize.Lanczos3)
+
+ out, err := os.Create("test_resized.jpg")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer out.Close()
+
+ // write new image to file
+ jpeg.Encode(out, m, nil)
+}
+```
+
+Caveats
+-------
+
+* Optimized access routines are used for `image.RGBA`, `image.NRGBA`, `image.RGBA64`, `image.NRGBA64`, `image.YCbCr`, `image.Gray`, and `image.Gray16` types. All other image types are accessed in a generic way that will result in slow processing speed.
+* JPEG images are stored in `image.YCbCr`. This image format stores data in a way that will decrease processing speed. A resize may be up to 2 times slower than with `image.RGBA`.
+
+
+Downsizing Samples
+-------
+
+Downsizing is not as simple as it might look like. Images have to be filtered before they are scaled down, otherwise aliasing might occur.
+Filtering is highly subjective: Applying too much will blur the whole image, too little will make aliasing become apparent.
+Resize tries to provide sane defaults that should suffice in most cases.
+
+### Artificial sample
+
+Original image
+![Rings](http://nfnt.github.com/img/rings_lg_orig.png)
+
+<table>
+<tr>
+<th><img src="http://nfnt.github.com/img/rings_300_NearestNeighbor.png" /><br>Nearest-Neighbor</th>
+<th><img src="http://nfnt.github.com/img/rings_300_Bilinear.png" /><br>Bilinear</th>
+</tr>
+<tr>
+<th><img src="http://nfnt.github.com/img/rings_300_Bicubic.png" /><br>Bicubic</th>
+<th><img src="http://nfnt.github.com/img/rings_300_MitchellNetravali.png" /><br>Mitchell-Netravali</th>
+</tr>
+<tr>
+<th><img src="http://nfnt.github.com/img/rings_300_Lanczos2.png" /><br>Lanczos2</th>
+<th><img src="http://nfnt.github.com/img/rings_300_Lanczos3.png" /><br>Lanczos3</th>
+</tr>
+</table>
+
+### Real-Life sample
+
+Original image
+![Original](http://nfnt.github.com/img/IMG_3694_720.jpg)
+
+<table>
+<tr>
+<th><img src="http://nfnt.github.com/img/IMG_3694_300_NearestNeighbor.png" /><br>Nearest-Neighbor</th>
+<th><img src="http://nfnt.github.com/img/IMG_3694_300_Bilinear.png" /><br>Bilinear</th>
+</tr>
+<tr>
+<th><img src="http://nfnt.github.com/img/IMG_3694_300_Bicubic.png" /><br>Bicubic</th>
+<th><img src="http://nfnt.github.com/img/IMG_3694_300_MitchellNetravali.png" /><br>Mitchell-Netravali</th>
+</tr>
+<tr>
+<th><img src="http://nfnt.github.com/img/IMG_3694_300_Lanczos2.png" /><br>Lanczos2</th>
+<th><img src="http://nfnt.github.com/img/IMG_3694_300_Lanczos3.png" /><br>Lanczos3</th>
+</tr>
+</table>
+
+
+License
+-------
+
+Copyright (c) 2012 Jan Schlicht <janschlicht@gmail.com>
+Resize is released under a MIT style license.
diff --git a/Godeps/_workspace/src/github.com/stretchr/objx/README.md b/Godeps/_workspace/src/github.com/stretchr/objx/README.md
new file mode 100644
index 000000000..4aa180687
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/stretchr/objx/README.md
@@ -0,0 +1,3 @@
+# objx
+
+ * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx)
diff --git a/Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md b/Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md
new file mode 100644
index 000000000..d5cd4e74b
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/vaughan0/go-ini/README.md
@@ -0,0 +1,70 @@
+go-ini
+======
+
+INI parsing library for Go (golang).
+
+View the API documentation [here](http://godoc.org/github.com/vaughan0/go-ini).
+
+Usage
+-----
+
+Parse an INI file:
+
+```go
+import "github.com/vaughan0/go-ini"
+
+file, err := ini.LoadFile("myfile.ini")
+```
+
+Get data from the parsed file:
+
+```go
+name, ok := file.Get("person", "name")
+if !ok {
+ panic("'name' variable missing from 'person' section")
+}
+```
+
+Iterate through values in a section:
+
+```go
+for key, value := range file["mysection"] {
+ fmt.Printf("%s => %s\n", key, value)
+}
+```
+
+Iterate through sections in a file:
+
+```go
+for name, section := range file {
+ fmt.Printf("Section name: %s\n", name)
+}
+```
+
+File Format
+-----------
+
+INI files are parsed by go-ini line-by-line. Each line may be one of the following:
+
+ * A section definition: [section-name]
+ * A property: key = value
+ * A comment: #blahblah _or_ ;blahblah
+ * Blank. The line will be ignored.
+
+Properties defined before any section headers are placed in the default section, which has
+the empty string as it's key.
+
+Example:
+
+```ini
+# I am a comment
+; So am I!
+
+[apples]
+colour = red or green
+shape = applish
+
+[oranges]
+shape = square
+colour = blue
+```
diff --git a/Godeps/_workspace/src/gopkg.in/bufio.v1/README.md b/Godeps/_workspace/src/gopkg.in/bufio.v1/README.md
new file mode 100644
index 000000000..bfb85ee54
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/bufio.v1/README.md
@@ -0,0 +1,4 @@
+bufio
+=====
+
+This is a fork of the http://golang.org/pkg/bufio/ package. It adds `ReadN` method that allows reading next `n` bytes from the internal buffer without allocating intermediate buffer. This method works just like the [Buffer.Next](http://golang.org/pkg/bytes/#Buffer.Next) method, but has slightly different signature.
diff --git a/Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md
new file mode 100644
index 000000000..7a0b24736
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/fsnotify.v1/README.md
@@ -0,0 +1,59 @@
+# File system notifications for Go
+
+[![Coverage](http://gocover.io/_badge/github.com/go-fsnotify/fsnotify)](http://gocover.io/github.com/go-fsnotify/fsnotify) [![GoDoc](https://godoc.org/gopkg.in/fsnotify.v1?status.svg)](https://godoc.org/gopkg.in/fsnotify.v1)
+
+Go 1.3+ required.
+
+Cross platform: Windows, Linux, BSD and OS X.
+
+|Adapter |OS |Status |
+|----------|----------|----------|
+|inotify |Linux, Android\*|Supported [![Build Status](https://travis-ci.org/go-fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/go-fsnotify/fsnotify)|
+|kqueue |BSD, OS X, iOS\*|Supported [![Circle CI](https://circleci.com/gh/go-fsnotify/fsnotify.svg?style=svg)](https://circleci.com/gh/go-fsnotify/fsnotify)|
+|ReadDirectoryChangesW|Windows|Supported [![Build status](https://ci.appveyor.com/api/projects/status/ivwjubaih4r0udeh/branch/master?svg=true)](https://ci.appveyor.com/project/NathanYoungman/fsnotify/branch/master)|
+|FSEvents |OS X |[Planned](https://github.com/go-fsnotify/fsnotify/issues/11)|
+|FEN |Solaris 11 |[Planned](https://github.com/go-fsnotify/fsnotify/issues/12)|
+|fanotify |Linux 2.6.37+ | |
+|USN Journals |Windows |[Maybe](https://github.com/go-fsnotify/fsnotify/issues/53)|
+|Polling |*All* |[Maybe](https://github.com/go-fsnotify/fsnotify/issues/9)|
+
+\* Android and iOS are untested.
+
+Please see [the documentation](https://godoc.org/gopkg.in/fsnotify.v1) for usage. Consult the [Wiki](https://github.com/go-fsnotify/fsnotify/wiki) for the FAQ and further information.
+
+## API stability
+
+Two major versions of fsnotify exist.
+
+**[fsnotify.v0](https://gopkg.in/fsnotify.v0)** is API-compatible with [howeyc/fsnotify](https://godoc.org/github.com/howeyc/fsnotify). Bugfixes *may* be backported, but I recommend upgrading to v1.
+
+```go
+import "gopkg.in/fsnotify.v0"
+```
+
+\* Refer to the package as fsnotify (without the .v0 suffix).
+
+**[fsnotify.v1](https://gopkg.in/fsnotify.v1)** provides [a new API](https://godoc.org/gopkg.in/fsnotify.v1) based on [this design document](http://goo.gl/MrYxyA). You can import v1 with:
+
+```go
+import "gopkg.in/fsnotify.v1"
+```
+
+Further API changes are [planned](https://github.com/go-fsnotify/fsnotify/milestones), but a new major revision will be tagged, so you can depend on the v1 API.
+
+**Master** may have unreleased changes. Use it to test the very latest code or when [contributing][], but don't expect it to remain API-compatible:
+
+```go
+import "github.com/go-fsnotify/fsnotify"
+```
+
+## Contributing
+
+Please refer to [CONTRIBUTING][] before opening an issue or pull request.
+
+## Example
+
+See [example_test.go](https://github.com/go-fsnotify/fsnotify/blob/master/example_test.go).
+
+
+[contributing]: https://github.com/go-fsnotify/fsnotify/blob/master/CONTRIBUTING.md
diff --git a/Godeps/_workspace/src/gopkg.in/redis.v2/README.md b/Godeps/_workspace/src/gopkg.in/redis.v2/README.md
new file mode 100644
index 000000000..ddf875f9a
--- /dev/null
+++ b/Godeps/_workspace/src/gopkg.in/redis.v2/README.md
@@ -0,0 +1,46 @@
+Redis client for Golang [![Build Status](https://travis-ci.org/go-redis/redis.png?branch=master)](https://travis-ci.org/go-redis/redis)
+=======================
+
+Supports:
+
+- Redis 2.8 commands except QUIT, MONITOR, SLOWLOG and SYNC.
+- Pub/sub.
+- Transactions.
+- Pipelining.
+- Connection pool.
+- TLS connections.
+- Thread safety.
+- Timeouts.
+- Redis Sentinel.
+
+API docs: http://godoc.org/gopkg.in/redis.v2.
+Examples: http://godoc.org/gopkg.in/redis.v2#pkg-examples.
+
+Installation
+------------
+
+Install:
+
+ go get gopkg.in/redis.v2
+
+Look and feel
+-------------
+
+Some corner cases:
+
+ SORT list LIMIT 0 2 ASC
+ vals, err := client.Sort("list", redis.Sort{Offset: 0, Count: 2, Order: "ASC"}).Result()
+
+ ZRANGEBYSCORE zset -inf +inf WITHSCORES LIMIT 0 2
+ vals, err := client.ZRangeByScoreWithScores("zset", redis.ZRangeByScore{
+ Min: "-inf",
+ Max: "+inf",
+ Offset: 0,
+ Count: 2,
+ }).Result()
+
+ ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE SUM
+ vals, err := client.ZInterStore("out", redis.ZStore{Weights: []int64{2, 3}}, "zset1", "zset2").Result()
+
+ EVAL "return {KEYS[1],ARGV[1]}" 1 "key" "hello"
+ vals, err := client.Eval("return {KEYS[1],ARGV[1]}", []string{"key"}, []string{"hello"}).Result()
diff --git a/LICENSE.txt b/LICENSE.txt
index 091e9c4b0..82a14ab91 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -24,7 +24,7 @@ Mattermost server and you’re only linking directly to or changing Admin Tools
are released under an Apache 2.0 license, and copyleft free.
We promise that we will not enforce the copyleft provisions in AGPL v3.0 against you if your application (a) does
-not link to the Mattermost server directly, but exclusively uses the Mattermost Admin Tools and Configuration files,
+not link to the Mattermost server directly, but exclusively uses the Mattermost Admin Tools and Configuration Files,
and (b) you have not modified, added to or adapted the source code of Mattermost in a way that results in the creation
of a “modified version” or “work based on” Mattermost as these terms are defined in the AGPL v3.0 license.
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..c2b0fbf2d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,128 @@
+**Mattermost Preview**
+**Team Communication Service**
+**Version 0.50**
+
+
+About Mattermost
+================
+
+Mattermost is a team communication service. It brings team messaging and file sharing into one place, accessible across PCs and phones, with archiving and search.
+
+We built Mattermost to help teams focus on what matters most to them. It works for us, we hope it works for you too.
+
+
+Installing the Mattermost
+=========================
+
+You're installing "Mattermost Preview", a pre-released 0.50 version intended for an early look at what we're building. While SpinPunch runs this version internally, it's not recommended for production deployments since we can't guarantee API stability or backwards compatibility until our 1.0 version release.
+
+That said, any issues at all, please let us know on the Mattermost forum at: http://bit.ly/1MY1kul
+
+Local Machine Setup (Docker)
+-----------------------------
+
+### Mac OSX ###
+
+1. Follow the instructions at http://docs.docker.com/installation/mac/
+ 1. Use the Boot2Docker command-line utility
+ 2. If you do command-line setup use: `boot2docker init eval “$(boot2docker shellinit)”`
+2. Get your Docker IP address with `boot2docker ip`
+3. Add a line to your /etc/hosts that goes `<Docker IP> dockerhost`
+4. Run `boot2docker shellinit` and copy the export statements to your ~/.bash\_profile
+5. Run `docker run --name mattermost-dev -d --publish 8065:80 mattermost/platform:helium`
+6. When docker is done fetching the image, open http://dockerhost:8065/ in your browser
+
+### Ubuntu ###
+1. Follow the instructions at https://docs.docker.com/installation/ubuntulinux/ or use the summery below.
+
+`sudo apt-get update`
+
+`sudo apt-get install wget`
+
+`wget -qO- https://get.docker.com/ | sh`
+
+`sudo usermod -aG docker <username>`
+
+`sudo service docker start`
+
+`newgrp docker`
+
+2. Run `docker run --name mattermost-dev -d --publish 8065:80 mattermost/platform:helium
+3. When docker is done fetching the image, open http://localhost:8065/ in your browser
+
+### Arch ###
+1. Install docker using the following commands
+
+`pacman -S docker`
+
+`systemctl enable docker.service`
+
+`systemctl start docker.service`
+
+`gpasswd -a <username> docker`
+
+`newgrp docker`
+
+2. docker run --name mattermost-dev -d --publish 8065:80 mattermost/platform:helium
+3. When docker is done fetching the image, open http://localhost:8065/ in your browser
+
+### Notes ###
+If your ISP blocks port 25 then you may install locally but email will not be sent.
+
+If you want to work with the latest bits in the repo you can run the cmd
+`docker run --name mattermost-dev -d --publish 8065:80 mattermost/platform:latest`
+
+You can update to the latest bits by running
+`docker pull mattermost/platform:latest`
+
+If you wish to remove mattermost-dev use the following commands
+
+1. `docker stop mattermost-dev`
+2. `docker rm -v mattermost-dev`
+
+
+AWS Elastic Beanstalk Setup (Docker)
+------------------------------------
+
+1. Create a new elastic beanstalk docker application using the Dockerrun.aws.json file provided.
+ 1. From the AWS console select Elastic Beanstalk
+ 2. Select "Create New Application" from the top right.
+ 3. Name the application and press next
+ 4. Select "Create a web server" environment.
+ 5. If asked, select create and AIM role and instance profile and press next.
+ 6. For predefined configuration select docker. For environment type select single instance.
+ 7. For application source, select upload your own and upload Dockerrun.aws.json from docker/Dockerrun.aws.json. Everything else may be left at default.
+ 8. Select an environment name, this is how you will refer to your environment. Make sure the URL is available then press next.
+ 9. The options on the additional resources page may be left at default unless you wish to change them. Press Next.
+ 10. On the configuration details place. Select an instance type of t2.small or larger.
+ 11. You can set the configuration details as you please but they may be left at their defaults. When you are done press next.
+ 12. Environment tags my be left blank. Press next.
+ 13. You will be asked to review your information. Press Launch.
+ 14. Up near the top of the dashboard you will see a domain of the form \*.elasticbeanstalk.com copy this as you will need it later.
+
+2. Map a wildcard domain to the new elastic beanstalk application
+ 15. From the AWS console select route 53
+ 16. From the sidebar select Hosted Zones
+ 17. Select the domain you want to use or create a new one.
+ 18. Modify an existing CNAME record set or create a new one with the name * and the value of the domain you copied in step 1.13.
+ 19. Save the record set
+
+3. Set the enviroment variable "MATTERMOST\_DOMAIN" to the domain you mapped above (example.com not www.example.com)
+ 20. Return the Elastic Beanstalk from the AWS console.
+ 21. Select the environment you created.
+ 22. Select configuration from the sidebar.
+ 23. Click the gear beside software configuration.
+ 24. Add an environment property with the name “MATTERMOST\_DOMAIN” and a value of the domain you mapped in route 53. For example if your domain is \*.example.com you would enter example.com not www.example.com.
+ 25. Select apply.
+
+4. Try it out!
+ 26. Return to the dashboard on the sidebar and wait for beanstalk update the environment.
+ 27. Try it out by entering the domain you mapped into your browser.
+
+License
+-------
+
+Most Mattermost source files are made available under the terms of the GNU Affero General Public License (AGPL). See individual files for details.
+
+As an exception, Admin Tools and Configuration Files are are made available under the terms of the Apache License, version 2.0. See LICENSE.txt for more information.
+