diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..163eb75
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*.cr]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0bb75ea
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/docs/
+/lib/
+/bin/
+/.shards/
+*.dwarf
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..151a16e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,65 @@
+Microsoft Public License (Ms-PL)
+
+This license governs use of the accompanying software. If you use the
+software, you accept this license. If you do not accept the license,
+do not use the software.
+
+1. Definitions
+
+ The terms "reproduce," "reproduction," "derivative works," and
+ "distribution" have the same meaning here as under U.S. copyright
+ law.
+
+ A "contribution" is the original software, or any additions or
+ changes to the software.
+
+ A "contributor" is any person that distributes its contribution
+ under this license.
+
+ "Licensed patents" are a contributor's patent claims that read
+ directly on its contribution.
+
+2. Grant of Rights
+
+ (A) Copyright Grant- Subject to the terms of this license,
+ including the license conditions and limitations in section 3,
+ each contributor grants you a non-exclusive, worldwide,
+ royalty-free copyright license to reproduce its contribution,
+ prepare derivative works of its contribution, and distribute its
+ contribution or any derivative works that you create.
+
+ (B) Patent Grant- Subject to the terms of this license, including
+ the license conditions and limitations in section 3, each
+ contributor grants you a non-exclusive, worldwide, royalty-free
+ license under its licensed patents to make, have made, use, sell,
+ offer for sale, import, and/or otherwise dispose of its
+ contribution in the software or derivative works of the
+ contribution in the software.
+
+3. Conditions and Limitations
+
+ (A) No Trademark License- This license does not grant you rights
+ to use any contributors' name, logo, or trademarks.
+
+ (B) If you bring a patent claim against any contributor over
+ patents that you claim are infringed by the software, your patent
+ license from such contributor to the software ends automatically.
+
+ (C) If you distribute any portion of the software, you must retain
+ all copyright, patent, trademark, and attribution notices that are
+ present in the software.
+
+ (D) If you distribute any portion of the software in source code
+ form, you may do so only under this license by including a
+ complete copy of this license with your distribution. If you
+ distribute any portion of the software in compiled or object code
+ form, you may only do so under a license that complies with this
+ license.
+
+ (E) The software is licensed "as-is." You bear the risk of using
+ it. The contributors give no express warranties, guarantees, or
+ conditions. You may have additional consumer rights under your
+ local laws which this license cannot change. To the extent
+ permitted under your local laws, the contributors exclude the
+ implied warranties of merchantability, fitness for a particular
+ purpose and non-infringement.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c25fb9a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+# rethink: it's all in your head.
+rethink is an experiment on making content for yourself and nobody else.
+
+rethink is meant for the rawest form of expression.
+
+rethink does not include any discoverability, markdown, or thought creation frontend.
+
+your thoughts do not need to be comprehensible to anyone other than yourself.
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..992ea22
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,32 @@
+
+
+
+ rethink: it's all in your head.
+
+
+
+
rethink.
+ it's all in your head.
+
+
\ No newline at end of file
diff --git a/shard.lock b/shard.lock
new file mode 100644
index 0000000..8782f73
--- /dev/null
+++ b/shard.lock
@@ -0,0 +1,30 @@
+version: 2.0
+shards:
+ backtracer:
+ git: https://github.com/sija/backtracer.cr.git
+ version: 1.2.2
+
+ crystal-argon2:
+ git: https://github.com/sushichain/crystal-argon2.git
+ version: 0.1.3
+
+ db:
+ git: https://github.com/crystal-lang/crystal-db.git
+ version: 0.11.0
+
+ exception_page:
+ git: https://github.com/crystal-loot/exception_page.git
+ version: 0.3.0
+
+ kemal:
+ git: https://github.com/kemalcr/kemal.git
+ version: 1.3.0
+
+ radix:
+ git: https://github.com/luislavena/radix.git
+ version: 0.4.1
+
+ sqlite3:
+ git: https://github.com/crystal-lang/crystal-sqlite3.git
+ version: 0.19.0
+
diff --git a/shard.yml b/shard.yml
new file mode 100644
index 0000000..95f7466
--- /dev/null
+++ b/shard.yml
@@ -0,0 +1,26 @@
+name: rethink
+version: 0.1.0
+
+authors:
+ - toonlink
+
+dependencies:
+ kemal:
+ github: kemalcr/kemal
+
+ db:
+ github: crystal-lang/crystal-db
+
+ sqlite3:
+ github: crystal-lang/crystal-sqlite3
+
+ crystal-argon2:
+ github: sushichain/crystal-argon2
+
+targets:
+ rethink:
+ main: src/rethink.cr
+
+crystal: 1.7.2
+
+license: Ms-PL
\ No newline at end of file
diff --git a/src/migrate.cr b/src/migrate.cr
new file mode 100644
index 0000000..f47ebb6
--- /dev/null
+++ b/src/migrate.cr
@@ -0,0 +1,17 @@
+require "db"
+require "sqlite3"
+
+db = DB.open "sqlite3:./rethink.sqlite"
+
+db.exec("CREATE TABLE IF NOT EXISTS users (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ name TEXT,
+ thought_key TEXT
+ )")
+
+db.exec("CREATE TABLE IF NOT EXISTS thoughts (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ author_id INTEGER,
+ content TEXT,
+ date DATE DEFAULT (datetime('now', 'localtime'))
+ )")
\ No newline at end of file
diff --git a/src/rethink.cr b/src/rethink.cr
new file mode 100644
index 0000000..6ff976b
--- /dev/null
+++ b/src/rethink.cr
@@ -0,0 +1,105 @@
+require "kemal"
+require "db"
+require "sqlite3"
+require "crystal-argon2"
+require "ecr"
+
+db = DB.open "sqlite3:./rethink.sqlite"
+
+class Thought
+ property :content, :date
+
+ def initialize(content : String, date : Time)
+ @content = content
+ @date = date
+ end
+end
+
+class Thoughts
+ def initialize(@thoughts : Array(Thought)) end
+
+ ECR.def_to_s "src/views/thoughts.ecr"
+end
+
+get "/~:name" do |ctx|
+ name = ctx.params.url["name"]
+ thoughts = [] of Thought
+
+ id : Int32? = nil
+ db.query("SELECT id FROM users WHERE name = ?", name) do |rows|
+ rows.each do
+ id = rows.read(Int32)
+ end
+ end
+
+ if id.nil?
+ ctx.response.status_code = 404
+ next "User not found"
+ end
+
+ db.query("SELECT content, date FROM thoughts WHERE author_id = ?", id) do |rows|
+ rows.each do
+ content = rows.read(String)
+ date = rows.read(Time)
+ thoughts << Thought.new(content, date)
+ end
+ end
+
+ Thoughts.new(thoughts).to_s
+end
+
+get "/" do
+ render "public/index.html"
+end
+
+# Reuse this later for population scripts
+# get "/api/hash" do |ctx|
+# Argon2::Password.create(ctx.request.body.as(IO).gets_to_end)
+# end
+
+# post to rethink
+put "/api/think" do |ctx|
+ unless ctx.request.headers.has_key?("authorization") || ctx.request.headers.has_key?("name")
+ ctx.response.status_code = 401
+ next "Unauthorized"
+ end
+
+ auth = ctx.request.headers["authorization"]
+ username = ctx.request.headers["name"]
+
+ id : Int32? = nil
+ thought_key = ""
+
+ db.query("SELECT id, thought_key FROM users WHERE name = ?", username) do |rows|
+ rows.each do
+ id = rows.read(Int32)
+ thought_key = rows.read(String)
+ end
+ end
+
+ authorized : Argon2::Response? = nil
+ begin
+ authorized = Argon2::Password.verify_password(auth, thought_key)
+ rescue ex
+ end
+
+ unless authorized == Argon2::Response::ARGON2_OK
+ ctx.response.status_code = 401
+ next "Unauthorized"
+ end
+
+ thought = if ctx.request.body.nil?
+ ""
+ else
+ ctx.request.body.as(IO).gets_to_end
+ end
+ db.exec("INSERT INTO thoughts (author_id, content) VALUES (?, ?)", id, thought)
+ ctx.response.status_code = 201
+end
+
+begin
+ Kemal.config.env = "production"
+ Kemal.run
+ensure
+ db.close
+end
\ No newline at end of file
diff --git a/src/views/thoughts.ecr b/src/views/thoughts.ecr
new file mode 100644
index 0000000..9a0e92b
--- /dev/null
+++ b/src/views/thoughts.ecr
@@ -0,0 +1,41 @@
+
+
+
+ rethink: it's all in your head.
+
+
+
+
rethink.
+ it's all in your head.
+
+<%- @thoughts.reverse.each do |thought| -%>
+
+
<%= thought.content %>
+
<%= thought.date.to_s("%a %h %H:%M:%S %Y") %>
+
+<%- end -%>
+
\ No newline at end of file