aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEv Bogue <ev@evbogue.com>2019-04-03 20:03:30 -0500
committerEv Bogue <ev@evbogue.com>2019-04-03 20:03:30 -0500
commit8856e4b188eadcf286c07e04e7478f2050af7d70 (patch)
tree030fe146f3e1f574500f83ad7db0ad3731a5638c
initial commit
-rw-r--r--.gitignore1
-rw-r--r--app.js193
-rw-r--r--css/source-sans-pro.min.css1
-rw-r--r--css/style.css110
-rwxr-xr-xfonts/EOT/SourceSansPro-Black.eotbin0 -> 289854 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-BlackIt.eotbin0 -> 103094 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-Bold.eotbin0 -> 291890 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-BoldIt.eotbin0 -> 103342 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-ExtraLight.eotbin0 -> 291994 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-ExtraLightIt.eotbin0 -> 104482 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-It.eotbin0 -> 103934 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-Light.eotbin0 -> 293630 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-LightIt.eotbin0 -> 104334 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-Regular.eotbin0 -> 294262 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-Semibold.eotbin0 -> 292794 bytes
-rwxr-xr-xfonts/EOT/SourceSansPro-SemiboldIt.eotbin0 -> 103686 bytes
-rwxr-xr-xfonts/LICENSE.txt93
-rwxr-xr-xfonts/OTF/SourceSansPro-Black.otfbin0 -> 238112 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-BlackIt.otfbin0 -> 83512 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-Bold.otfbin0 -> 239148 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-BoldIt.otfbin0 -> 82472 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-ExtraLight.otfbin0 -> 226624 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-ExtraLightIt.otfbin0 -> 78704 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-It.otfbin0 -> 81672 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-Light.otfbin0 -> 230688 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-LightIt.otfbin0 -> 79728 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-Regular.otfbin0 -> 234960 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-Semibold.otfbin0 -> 238044 bytes
-rwxr-xr-xfonts/OTF/SourceSansPro-SemiboldIt.otfbin0 -> 82620 bytes
-rwxr-xr-xfonts/README.md20
-rwxr-xr-xfonts/ReadMe.html72
-rwxr-xr-xfonts/SourceSansProReadMe.html274
-rwxr-xr-xfonts/TTF/SourceSansPro-Black.ttfbin0 -> 289528 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-BlackIt.ttfbin0 -> 102756 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-Bold.ttfbin0 -> 291584 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-BoldIt.ttfbin0 -> 103008 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-ExtraLight.ttfbin0 -> 291648 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-ExtraLightIt.ttfbin0 -> 104124 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-It.ttfbin0 -> 103620 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-Light.ttfbin0 -> 293304 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-LightIt.ttfbin0 -> 103996 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-Regular.ttfbin0 -> 293960 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-Semibold.ttfbin0 -> 292456 bytes
-rwxr-xr-xfonts/TTF/SourceSansPro-SemiboldIt.ttfbin0 -> 103336 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-Black.otf.woffbin0 -> 132224 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-BlackIt.otf.woffbin0 -> 54204 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-Bold.otf.woffbin0 -> 135828 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-BoldIt.otf.woffbin0 -> 54292 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-ExtraLight.otf.woffbin0 -> 124560 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-ExtraLightIt.otf.woffbin0 -> 50064 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-It.otf.woffbin0 -> 53852 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-Light.otf.woffbin0 -> 129732 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-LightIt.otf.woffbin0 -> 52320 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-Regular.otf.woffbin0 -> 133352 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-Semibold.otf.woffbin0 -> 134540 bytes
-rwxr-xr-xfonts/WOFF/OTF/SourceSansPro-SemiboldIt.otf.woffbin0 -> 54260 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-Black.ttf.woffbin0 -> 122964 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-BlackIt.ttf.woffbin0 -> 51476 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-Bold.ttf.woffbin0 -> 127376 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-BoldIt.ttf.woffbin0 -> 52452 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-ExtraLight.ttf.woffbin0 -> 123432 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-ExtraLightIt.ttf.woffbin0 -> 51488 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-It.ttf.woffbin0 -> 52908 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-Light.ttf.woffbin0 -> 127508 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-LightIt.ttf.woffbin0 -> 52828 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-Regular.ttf.woffbin0 -> 128612 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-Semibold.ttf.woffbin0 -> 127760 bytes
-rwxr-xr-xfonts/WOFF/TTF/SourceSansPro-SemiboldIt.ttf.woffbin0 -> 52716 bytes
-rwxr-xr-xfonts/bower.json17
-rwxr-xr-xfonts/source-sans-pro.css131
-rw-r--r--index.html13
-rw-r--r--lib.js264
-rw-r--r--nacl-util.min.js1
-rw-r--r--nacl.min.js1
-rw-r--r--package-lock.json65
-rw-r--r--package.json17
-rw-r--r--readme.md65
-rw-r--r--server.js58
78 files changed, 1396 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/app.js b/app.js
new file mode 100644
index 0000000..da1a07c
--- /dev/null
+++ b/app.js
@@ -0,0 +1,193 @@
+var screen = h('div', {id: 'screen'})
+
+document.body.appendChild(screen)
+
+var header = h('div', {classList: 'message'})
+
+var keys = getKeys()
+
+function compose (keys, opts) {
+ var header = h('div', {classList: 'message'})
+ var scroller = document.getElementById('scroller')
+
+ scroller.insertBefore(header, scroller.firstChild)
+
+ var textarea = h('textarea', {placeholder: 'Write a new bog post'})
+
+ header.appendChild(textarea)
+
+ var composer = h('div', [
+ h('button', {
+ onclick: function () {
+ if (textarea.value) {
+ var content = {
+ author: keys.publicKey,
+ type: 'post',
+ text: textarea.value,
+ timestamp: Date.now()
+ }
+ textarea.value = ''
+ publish(content, keys)
+ }
+ }
+ }, ['Publish'])
+ ])
+
+ header.appendChild(composer)
+}
+
+function route () {
+ src = window.location.hash.substring(1)
+ var scroller = h('div', {id: 'scroller'})
+ var screen = document.getElementById('screen')
+
+
+ screen.appendChild(scroller)
+
+ if (src === 'key') {
+ var keyMessage = h('div', {classList: 'message'})
+
+ // delete key button
+ keyMessage.appendChild(h('button', {classList: 'right',
+ onclick: function () {
+ localStorage['id'] = ''
+ location.reload()
+ }
+ }, ['Delete Key']))
+
+ // print stringified keypair
+ keyMessage.appendChild(h('pre', {style: 'width: 80%'}, [h('code', [JSON.stringify(keys)])]))
+
+ scroller.appendChild(keyMessage)
+ }
+
+ else if (src[0] === '@') {
+ var profile = h('div', {classList: 'message'})
+ scroller.appendChild(profile)
+
+ var nameInput = h('input', {placeholder: 'Publish a new name'})
+
+ var namePublisher = h('div',[
+ nameInput,
+ h('button', {
+ onclick: function () {
+ if (nameInput.value) {
+
+ var content = {
+ author: keys.publicKey,
+ type: 'name',
+ text: nameInput.value,
+ timestamp: Date.now()
+ }
+
+ publish(content, keys)
+ }
+ }
+ }, ['Publish'])
+ ])
+
+ profile.appendChild(namePublisher)
+
+ readFile()
+
+ var imageInput = h('span', [
+ h('input', {id: 'inp', type:'file'}),
+ h('span', {id: 'b64'}),
+ h('img', {id: 'img'})
+ ])
+
+ var imagePublisher = h('div', [
+ imageInput,
+ h('button', {
+ onclick: function () {
+ var content = {
+ author: keys.publicKey,
+ type: 'image',
+ image: document.getElementById("img").src,
+ timestamp: Date.now()
+ }
+
+ publish(content, keys)
+ }
+ }, ['Publish'])
+ ])
+
+ profile.appendChild(imagePublisher)
+
+ document.getElementById("inp").addEventListener("change", readFile);
+
+
+ var ws = new WebSocket('ws://localhost:8080/' + src)
+
+ var clientLog = {
+ publicKey: src
+ }
+
+ if (localStorage[src]) {
+ clientLog.log = JSON.parse(localStorage[src])
+ } else {
+ clientLog.log = []
+ }
+
+ /*if (localSTorage['log']) {
+ var publicLog = localStorage['log']
+ } else {
+ var publicLog = []
+ }*/
+
+ ws.onopen = function () {
+ ws.send(JSON.stringify(clientLog))
+ }
+
+ ws.onmessage = function (ev) {
+ var serverData = JSON.parse(ev.data)
+ if (serverData.log.length > clientLog.log.length) {
+ localStorage[src] = JSON.stringify(serverData.log)
+ location.reload()
+ }
+ }
+
+ if (localStorage[src]) {
+ var log = JSON.parse(localStorage[src])
+ for (var i=0; i < log.length; i++) {
+ var post = log[i]
+ scroller.appendChild(renderMessage(post))
+ }
+ }
+ }
+
+ else if (src[0] === '%') {
+ if (localStorage['log']) {
+ var log = JSON.parse(localStorage['log'])
+ for (var i=0; i < log.length; i++) {
+ if (log[i].key === src) {
+ var post = log[i]
+ scroller.appendChild(renderMessage(post))
+ }
+ }
+ }
+ }
+
+ else {
+ compose(keys)
+ if (localStorage['log']) {
+ var log = JSON.parse(localStorage['log'])
+ for (var i=0; i < log.length; i++) {
+ var post = log[i]
+ scroller.appendChild(renderMessage(post))
+
+ }
+ }
+ }
+}
+
+
+route()
+
+window.onhashchange = function () {
+ var oldscreen = document.getElementById('screen')
+ var newscreen = h('div', {id: 'screen'})
+ oldscreen.parentNode.replaceChild(newscreen, oldscreen)
+ route()
+}
+
diff --git a/css/source-sans-pro.min.css b/css/source-sans-pro.min.css
new file mode 100644
index 0000000..dd82c44
--- /dev/null
+++ b/css/source-sans-pro.min.css
@@ -0,0 +1 @@
+@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:200;font-stretch:normal;src:local('SourceSansPro-ExtraLight'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-ExtraLight.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-ExtraLight.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-ExtraLight.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-ExtraLight.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:300;font-stretch:normal;src:local('SourceSansPro-Light'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-Light.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-Light.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-Light.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-Light.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;font-stretch:normal;src:local('SourceSansPro-Regular'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-Regular.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-Regular.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-Regular.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-Regular.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:600;font-stretch:normal;src:local('SourceSansPro-Semibold'),local('Source Sans Pro Semibold'),url(../fonts/EOT/SourceSansPro-Semibold.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-Semibold.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-Semibold.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-Semibold.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:700;font-stretch:normal;src:local('SourceSansPro-Bold'),local('Source Sans Pro Bold'),url(../fonts/EOT/SourceSansPro-Bold.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-Bold.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-Bold.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-Bold.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:900;font-stretch:normal;src:local('SourceSansPro-Black'),local('Source Sans Pro Black'),url(../fonts/EOT/SourceSansPro-Black.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-Black.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-Black.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-Black.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:200;font-stretch:normal;src:local('SourceSansPro-ExtraLightIt'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-ExtraLightIt.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-ExtraLightIt.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-ExtraLightIt.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-ExtraLightIt.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:300;font-stretch:normal;src:local('SourceSansPro-LightIt'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-LightIt.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-LightIt.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-LightIt.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-LightIt.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:400;font-stretch:normal;src:local('SourceSansPro-It'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-It.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-It.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-It.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-It.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:600;font-stretch:normal;src:local('SourceSansPro-SemiboldIt'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-SemiboldIt.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-SemiboldIt.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-SemiboldIt.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-SemiboldIt.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:700;font-stretch:normal;src:local('SourceSansPro-BoldIt'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-BoldIt.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-BoldIt.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-BoldIt.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-BoldIt.ttf) format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:900;font-stretch:normal;src:local('SourceSansPro-BlackIt'),local('Source Sans Pro'),url(../fonts/EOT/SourceSansPro-BlackIt.eot) format('embedded-opentype'),url(../fonts/WOFF/OTF/SourceSansPro-BlackIt.otf.woff) format('woff'),url(../fonts/OTF/SourceSansPro-BlackIt.otf) format('opentype'),url(../fonts/TTF/SourceSansPro-BlackIt.ttf) format('truetype')} \ No newline at end of file
diff --git a/css/style.css b/css/style.css
new file mode 100644
index 0000000..81894f4
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,110 @@
+body {
+ font-family: 'Source Sans Pro';
+ background: #222;
+ color: #f5f5f5;
+ max-width: 780px;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+p {
+ margin-top: 5px;
+ margin-bottom: 5px;
+ font-size: 1em;
+}
+
+#screen {
+ top: 0; right: 0; left: 0; bottom: 0;
+}
+
+.right { float: right;}
+
+.message {
+ background: #333;
+ margin-top: .5em;
+ padding: .5em;
+ border-radius: 5px;
+}
+
+img {
+ max-width: 100%;
+}
+
+img.small {
+ vertical-align: top;
+ width: 25px;
+ height: 25px;
+ margin-right: .2em;
+ border-radius: 3px;
+}
+
+a {
+ color: cyan;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+pre {
+ color: violet;
+ width: 100%;
+ display: block;
+}
+
+code {
+ display: inline-block;
+ vertical-align: bottom;
+}
+
+code, pre {
+ overflow: auto;
+ word-break: break-all;
+ word-wrap: break-word;
+ white-space: pre;
+ white-space: -moz-pre-wrap;
+ white-space: pre-wrap;
+ white-space: pre\9;
+}
+
+textarea, input {
+ background: #222;
+ padding: .5em;
+ color: #f5f5f5;
+ border: none;
+ border-radius: 5px;
+}
+
+textarea {
+ width: 100%;
+}
+
+
+button {
+ display: inline-block;
+ padding: 2px 6px;
+ margin: .2em .2em .2em 0em;
+ font-size: 14px;
+ line-height: 20px;
+ color: #d5d5d5;
+ text-align: center;
+ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
+ vertical-align: middle;
+ cursor: pointer;
+ background-color: #222;
+ border: 1px solid #222;
+ border-radius: 4px;
+}
+
+button:hover,
+button:focus,
+button:active {
+ color: white;
+ background-color: black;
+}
+
+button.active {
+ background-color: #111;
+}
+
diff --git a/fonts/EOT/SourceSansPro-Black.eot b/fonts/EOT/SourceSansPro-Black.eot
new file mode 100755
index 0000000..22772ee
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-Black.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-BlackIt.eot b/fonts/EOT/SourceSansPro-BlackIt.eot
new file mode 100755
index 0000000..5e3fc5b
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-BlackIt.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-Bold.eot b/fonts/EOT/SourceSansPro-Bold.eot
new file mode 100755
index 0000000..9f8ba46
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-Bold.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-BoldIt.eot b/fonts/EOT/SourceSansPro-BoldIt.eot
new file mode 100755
index 0000000..4af2784
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-BoldIt.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-ExtraLight.eot b/fonts/EOT/SourceSansPro-ExtraLight.eot
new file mode 100755
index 0000000..0a142d1
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-ExtraLight.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-ExtraLightIt.eot b/fonts/EOT/SourceSansPro-ExtraLightIt.eot
new file mode 100755
index 0000000..17d8432
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-ExtraLightIt.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-It.eot b/fonts/EOT/SourceSansPro-It.eot
new file mode 100755
index 0000000..bb3a732
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-It.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-Light.eot b/fonts/EOT/SourceSansPro-Light.eot
new file mode 100755
index 0000000..005d51f
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-Light.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-LightIt.eot b/fonts/EOT/SourceSansPro-LightIt.eot
new file mode 100755
index 0000000..e3933a1
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-LightIt.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-Regular.eot b/fonts/EOT/SourceSansPro-Regular.eot
new file mode 100755
index 0000000..1c20988
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-Regular.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-Semibold.eot b/fonts/EOT/SourceSansPro-Semibold.eot
new file mode 100755
index 0000000..7f7cd0e
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-Semibold.eot
Binary files differ
diff --git a/fonts/EOT/SourceSansPro-SemiboldIt.eot b/fonts/EOT/SourceSansPro-SemiboldIt.eot
new file mode 100755
index 0000000..c7efea1
--- /dev/null
+++ b/fonts/EOT/SourceSansPro-SemiboldIt.eot
Binary files differ
diff --git a/fonts/LICENSE.txt b/fonts/LICENSE.txt
new file mode 100755
index 0000000..87ec82c
--- /dev/null
+++ b/fonts/LICENSE.txt
@@ -0,0 +1,93 @@
+Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/fonts/OTF/SourceSansPro-Black.otf b/fonts/OTF/SourceSansPro-Black.otf
new file mode 100755
index 0000000..cdee743
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-Black.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-BlackIt.otf b/fonts/OTF/SourceSansPro-BlackIt.otf
new file mode 100755
index 0000000..2ae07ea
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-BlackIt.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-Bold.otf b/fonts/OTF/SourceSansPro-Bold.otf
new file mode 100755
index 0000000..33b4648
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-Bold.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-BoldIt.otf b/fonts/OTF/SourceSansPro-BoldIt.otf
new file mode 100755
index 0000000..4d30b7f
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-BoldIt.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-ExtraLight.otf b/fonts/OTF/SourceSansPro-ExtraLight.otf
new file mode 100755
index 0000000..0167d54
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-ExtraLight.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-ExtraLightIt.otf b/fonts/OTF/SourceSansPro-ExtraLightIt.otf
new file mode 100755
index 0000000..45c6fad
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-ExtraLightIt.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-It.otf b/fonts/OTF/SourceSansPro-It.otf
new file mode 100755
index 0000000..d1ccf45
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-It.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-Light.otf b/fonts/OTF/SourceSansPro-Light.otf
new file mode 100755
index 0000000..c94f961
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-Light.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-LightIt.otf b/fonts/OTF/SourceSansPro-LightIt.otf
new file mode 100755
index 0000000..e9c4885
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-LightIt.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-Regular.otf b/fonts/OTF/SourceSansPro-Regular.otf
new file mode 100755
index 0000000..55fc533
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-Regular.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-Semibold.otf b/fonts/OTF/SourceSansPro-Semibold.otf
new file mode 100755
index 0000000..c72879e
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-Semibold.otf
Binary files differ
diff --git a/fonts/OTF/SourceSansPro-SemiboldIt.otf b/fonts/OTF/SourceSansPro-SemiboldIt.otf
new file mode 100755
index 0000000..cde44e3
--- /dev/null
+++ b/fonts/OTF/SourceSansPro-SemiboldIt.otf
Binary files differ
diff --git a/fonts/README.md b/fonts/README.md
new file mode 100755
index 0000000..dcd8836
--- /dev/null
+++ b/fonts/README.md
@@ -0,0 +1,20 @@
+# Source Sans Pro
+
+Source Sans Pro is a set of OpenType fonts that have been designed to work well
+in user interface (UI) environments. In addition to a functional OpenType font, this open
+source project provides all of the source files that were used to build this OpenType font
+by using the AFDKO makeotf tool.
+
+## Installation instructions
+
+* [Mac OS X](http://support.apple.com/kb/HT2509)
+* [Windows](http://windows.microsoft.com/en-us/windows-vista/install-or-uninstall-fonts)
+* [Linux/Unix-based systems](https://github.com/adobe-fonts/source-code-pro/issues/17#issuecomment-8967116)
+
+## Getting Involved
+
+Send suggestions for changes to the Source Sans OpenType font project maintainer, [Paul D. Hunt](mailto:opensourcefonts@adobe.com?subject=[GitHub] Source Sans Pro), for consideration.
+
+## Further information
+
+For information about the design and background of Source Sans, please refer to the [official font readme file](http://htmlpreview.github.io/?https://github.com/adobe-fonts/source-sans-pro/blob/master/SourceSansProReadMe.html).
diff --git a/fonts/ReadMe.html b/fonts/ReadMe.html
new file mode 100755
index 0000000..1aeb775
--- /dev/null
+++ b/fonts/ReadMe.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Read Me File for Adobe® OpenType® Fonts</title>
+ <meta charset="utf-8" />
+</head>
+<body bgcolor="white" link="#ce0000" alink="#ce0000" vlink="#9c6363">
+ <h2><font color="#333333"
+face="verdana,geneva,arial">Adobe&reg; OpenType&reg; Fonts</font></h2>
+ <p><font size="2" face="verdana,geneva,arial">Thank
+you for licensing Adobe OpenType fonts. In order to ensure that you
+have the most up-to-date product information, Adobe has posted <a
+href="http://www.adobe.com/type/browser/OTReadMe.html">an OpenType
+Read Me file</a> on the Adobe web site that contains information such
+as minimum system requirements, technical support contact information
+and software installation notes. We have also posted <a
+href="http://www.adobe.com/type/browser/pdfs/OTGuide.pdf">an OpenType
+User's Guide</a> in PDF format on the Adobe web site that can be
+viewed online and downloaded to your computer. <P>If you have
+licensed an Adobe OpenType Pro font, there may be additional PDF
+documents, such as a specimen book, a glyph complement showing, and a
+typeface-specific Read Me file, available on the typeface&#146;s
+product pages on the Adobe web site. These additional files may be
+viewed online or downloaded to your computer.<P>To get you started
+quickly, below are links to localized installation instructions for
+your fonts.
+
+<h4>Installation Instructions</h4><hr>
+<p lang=en><b>English</b><br>
+Instructions for installing this font can be found online at <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p lang=fr><b>French / Fran&#231;ais</b><br>
+Le mode d'installation de cette police de caract&#232;re se trouve en
+ligne &#224; <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p lang=de><b>German / Deutsch</b><br>
+Die Anweisungen zur Installation dieser Schriftart finden Sie online
+unter <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p lang=it><b>Italian / Italiano</b><br>
+Le istruzioni per l'installazione di questo font sono disponibili
+online all'indirizzo <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p lang=es><b>Spanish / Espa&#241;ol</b><br>
+Las instrucciones para instalar esta fuente se pueden encontrar
+online en <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p lang=nl><b>Dutch / Hollands</b><br>
+De instructies voor de installatie van dit lettertype vindt u op <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p><b>Swedish / Svenska</b><br>
+Anvisningar f&#246;r hur det h&#228;r teckensnittet installeras finns
+online p&#229; <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p><b>Norwegian / Norsk</b><br>
+Instruksjoner for installering av skrifttypen finnes online p&#229;
+<a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p><b>Finnish / Suomi</b><br>
+Ohjeet t&#228;m&#228;n fontin asentamiseen l&#246;ytyv&#228;t
+osoitteesta <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p><b>Danish / Dansk</b><br>
+Du finder en vejledning i installation af denne skrifttype online
+p&#229; adressen <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>.</p>
+<p lang=ja><b>Japanese / 日本語</b><br>
+このフォントをインストールする手順は、オンラインで <a
+href="http://www.adobe.com/type/browser/fontinstall/instructions_main.html">http://www.adobe.com/type/browser/fontinstall/instructions_main.html</a>
+を参照してください。</p>
+</body>
+</html>
diff --git a/fonts/SourceSansProReadMe.html b/fonts/SourceSansProReadMe.html
new file mode 100755
index 0000000..13450b5
--- /dev/null
+++ b/fonts/SourceSansProReadMe.html
@@ -0,0 +1,274 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!-- Read-me Template Version 1.003 Jan 145 2013 -->
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html" />
+ <meta name="title" content="Read Me File for Source Sans Pro" />
+ <meta name="description" content="Read Me file for Source Sans Pro ..." />
+ <title>Source Sans Pro Read Me</title>
+ <style type="text/css" media="screen">
+ /*********************** fonts ************************/
+ body {font-family: sans-serif; font-weight: normal; font-size: 10pt; color: #000000; margin: 0px; background-color: white;}
+ h1 {display:inline; font-family: sans-serif; font-weight: normal; color: #999999;}
+ h2 {display:inline; font-size: 10pt; font-family: sans-serif; font-weight: bold; color: #666666;}
+ hFooter {font-family: sans-serif; font-weight: normal; font-size: 7pt; color: #000000; margin: 0px; background-color: white;}
+ /*********************** links ************************/
+ a:link {color:#004477; text-decoration:none; margin: 0px 0px 0px 0px;}
+ a:visited {color:#6d7f8e; text-decoration:none; margin: 0px 0px 0px 0px;}
+ a:hover {color:#ff0000; text-decoration:none; margin: 0px 0px 0px 0px;}
+ /*********************** div tags ************************/
+ #page {float:left; width:700px; margin:20px 20px 20px 20px;}
+ #subTitle {background-color:#e3e3e3; float:left; width:700px; border-bottom:solid #999999 1.0pt; border-bottom-alt:solid #999999 .5pt; padding:2px 0px 4px 0px;}
+ #title {background-color:#e3e3e3; float:left; width:700px; border-bottom:solid #999999 1.0pt; border-bottom-alt:solid #999999 .5pt; padding:2px 0px 4px 0px;}
+ #description {float:left; width:700px; padding:15px 0px 15px 0px;} .style6 {color: #666666} .style7 {color: #FF0000}</style>
+ </head>
+ <body>
+ <div id="page">
+ <h1>
+ <span style="font-size:16pt">Source Sans Pro Read Me</span>
+ </h1>
+ <br />
+ <div id="description">
+ <p>This document contains late-breaking product information, updates, and troubleshooting tips.
+ <br />
+ <br />
+ <a href="#A1">Minimum system requirements and font installation instructions</a>
+ <br />
+ <a href="#A2A">Font versions</a>
+ <br />
+ <a href="#A2">Family information</a>
+ <br />
+ <a href="#A3">Release Notes</a>
+ <br />
+ <a href="#A8">Known issues</a>
+ <br />
+ <a href="#A9">Customer care</a>
+ <br />
+ <a href="#A10">Other resources</a>
+ <br />
+ <a href="#A12"></a>
+ <br /></p>
+ </div>
+ <div id="title">
+ <a name="A1" id="A1"></a>
+ <h2>Minimum system requirements and font installation instructions</h2>
+ </div>
+ <div id="description">
+ <p>For information on minimum system requirements and font installation, see <span class="style7">
+ <a title="http://www.adobe.com/go/learn_fontinstall_en" href="http://www.adobe.com/go/learn_fontinstall_en">http://www.adobe.com/go/learn_fontinstall_en</a>.</span></p>
+ </div>
+ <div id="title">
+ <a name="A2A" id=A2A></a>
+ <h2>Font versions</h2>
+ </div>
+ <div id="description">
+ <p>To check that you have the correct font file, compare the font version of your font file to the font version provided in the Release Notes section below.</p>
+ </div>
+ <div id="title">
+ <h2>
+ <a name="A2" id="A2">Family information</a>
+ </h2>
+ </div>
+ <div id="description">
+ <p>
+ <strong>History</strong>
+ </p>Source Sans Pro was designed by Paul D. Hunt under the guidance of Robert Slimbach. It is Adobe's first open source typeface family, conceived primarily as a typeface for user interfaces. Source Sans Pro draws inspiration from the clarity and legibility of twentieth-century American gothic typeface designs. Distilling the best archetypical qualities of these models, Paul followed a rational design approach by simplifying glyph shapes by paring them to their essential form. However, in order to more easily differentiate similar letter shapes (such as uppercase I and lowercase L), some additional details have been added. Besides providing such explicitly clarity in short text strings, another fundamental design consideration was to create a typeface that reads well in extended settings. This can be seen in the general proportions: Source Sans Pro has been designed with a more generous width than many other comparable gothics, and its shorter majuscule letters, combined with minuscule letters with longer extenders, create a more pleasant reading texture in longer text passages.</p>
+<p>
+Source Sans Pro currently supports a wide range of languages using Latin script. The non-italic fonts also support both modern and polytonic Greek, as well as glyph coverage for extended Cyrillic. Other members of the greater Source type system include Source Code Pro, a monospaced version of Source Sans designed specifically for coding, and Source Serif Pro. As an open source project, it is expected that incremental updates will be made over time to extend glyph set coverage and functionality. If you are interested in contributing to this open source project, please visit this project page on GitHub for information on how to become involved. Source Sans Pro can be adapted and redistributed according to the terms of the Open Font License (OFL) agreement. </p>
+ <p>
+ <strong>Menu Names And Style Linking</strong>
+ </p>
+<p>In many Windows<sup>&reg;</sup> applications, instead of every font appearing on
+the menu, fonts are grouped into style-linked sets, and only the name of
+the base style font for a set is shown in the menu. The italic and the
+bold weight fonts of the set (if any) are not shown in the font menu, but can still be
+accessed by selecting the base style font, and then using the italic
+and bold style buttons. In this family, such programs will show only the
+following base style font names in the menu:</p>
+<p>Source Sans Pro<br>
+Source Sans Pro Black<br>
+Source Sans Pro ExtraLight<br>
+Source Sans Pro Light<br>
+Source Sans Pro SemiBold<br></p>
+<p>The other fonts in this family must be selected by choosing a menu name
+and then a style option following the guide below.</p>
+<table border="0">
+<tr> <td>Menu Name</td> <td> </td> <td>plus Style Option... </td> <td> </td> <td>selects this font</td> </tr>
+<tr> <td>Source Sans Pro</td> <td> </td> <td>[none]</td> <td> </td> <td>Source Sans Pro Regular</td> </tr>
+<tr> <td>Source Sans Pro</td> <td> </td> <td>Italic</td> <td> </td> <td>Source Sans Pro Italic</td> </tr>
+<tr> <td>Source Sans Pro</td> <td> </td> <td>Bold</td> <td> </td> <td>Source Sans Pro Bold</td> </tr>
+<tr> <td>Source Sans Pro</td> <td> </td> <td>Bold, Italic</td> <td> </td> <td>Source Sans Pro Bold Italic</td> </tr>
+<tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr>
+<tr> <td>Source Sans Pro Black</td> <td> </td> <td>[none]</td> <td> </td> <td>Source Sans Pro Black</td> </tr>
+<tr> <td>Source Sans Pro Black</td> <td> </td> <td>Italic</td> <td> </td> <td>Source Sans Pro Black Italic</td> </tr>
+<tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr>
+<tr> <td>Source Sans Pro ExtraLight</td> <td> </td> <td>[none]</td> <td> </td> <td>Source Sans Pro ExtraLight</td> </tr>
+<tr> <td>Source Sans Pro ExtraLight</td> <td> </td> <td>Italic</td> <td> </td> <td>Source Sans Pro ExtraLight Italic</td> </tr>
+<tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr>
+<tr> <td>Source Sans Pro Light</td> <td> </td> <td>[none]</td> <td> </td> <td>Source Sans Pro Light</td> </tr>
+<tr> <td>Source Sans Pro Light</td> <td> </td> <td>Italic</td> <td> </td> <td>Source Sans Pro Light Italic</td> </tr>
+<tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr>
+<tr> <td>Source Sans Pro SemiBold</td> <td> </td> <td>[none]</td> <td> </td> <td>Source Sans Pro Semibold</td> </tr>
+<tr> <td>Source Sans Pro SemiBold</td> <td> </td> <td>Italic</td> <td> </td> <td>Source Sans Pro Semibold Italic</td> </tr>
+<tr> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr>
+</table>
+<p>On the Mac OS operating system, although each font appears as a separate entry on the
+font menu, users may also select fonts by means of style links.
+Selecting a base style font and then using the style links (as described
+above for Windows applications) enhances cross-platform document compatibility with
+many applications, such as Microsoft Word and Adobe PageMaker software,
+although it is unnecessary with more sophisticated Adobe applications
+such as recent versions of Illustrator, Photoshop or
+InDesign software.</p>
+<p>One should not, however, select a base font which has no style-linked
+variant, and then use the bold or italic styling button. Doing so will
+either have no effect, or result in programmatic bolding or slanting of
+the base font, which will usually produce inferior screen and print
+results.</p>
+</div>
+ <div id="title">
+ <h2>
+ <a name="A3" id="A3">Release Notes</a>
+ </h2>
+ </div>
+ <div id="description"><p>For all Roman fonts of family Source Sans Pro: version 2.010 created on Fri Jun 27 11:31:39 2014.</p>
+ <p>For all Italic fonts of family Source Sans Pro: version 1.065 created on Wed Jun 25 13:50:02 2014.</p>
+
+<p>version 2.010 created 2014/06/27</p>
+<ul>
+<li> [This release is Roman fonts only]
+<li> Fixed inconsistencies in several derived glyphs.
+</ul>
+<p>version 2.005 created 2014/06/25</p>
+<ul>
+<li> [This release is Roman fonts only]
+<li> Fixed issue affecting composite glyphs with accents below in TrueType fonts.
+</ul>
+<p>version 1.065 created 2014/06/25</p>
+<ul>
+<li> [This release is Italic fonts only]
+<li> Fixed TT hinting issues in Ohorn and eight.
+<li> Adjusted the position of some accents over a.alt.
+<li> Fixed issue affecting composite glyphs with accents below in TrueType fonts.
+</ul>
+<p>version 2.000 created 2014/06/17</p>
+<ul>
+<li> [This release is Roman fonts only]</li>
+<li> Geometric shapes were made larger. (GitHub issue #39)</li>
+<li> Adds narrow no-break space [U+202F] (GitHub issue #30)</li>
+<li> Updates kerning of small caps and adds small cap punctuation (GitHub issues #15 & #27)</li>
+<li> Adds Cyrillic and Greek support (GitHub issues #6 & #38)</li>
+<li> Updates size and shape of diacritics (GitHub issue #21)</li>
+<li> Adjusts superscript height to coordinate baseline of letters and numbers (GitHub issue #18)</li>
+</ul>
+<p>version 1.060 created 2014/06/17</p>
+<ul>
+<li> [Italic fonts only] Updates size and shape of diacritics.</li>
+</ul>
+<p>version 1.050 created 2013/04/16</p>
+<ul>
+<li> [TrueType] Coordinated the vertical alignment of the tops of the letters across all
+ the styles at the various sizes. (GitHub issue #25)</li>
+</ul>
+<p>version 1.040 created 2013/04/08</p>
+<ul>
+<li> Adds Zero_Width_Non_Breaking_Space character (ZWNBS, U+FEFF) to address GitHub issue #20.</li>
+</ul>
+<p>version 1.039 created 2012/10/19</p>
+<ul>
+<li> Rebuilt fonts with new MakeOTF version.</li>
+</ul>
+<p>version 1.038 created 2012/10/15</p>
+<ul>
+<li> Updates TTF fonts with better hinting for asciitilde and approxequal, which references this hinting.</li>
+</ul>
+<p>version 1.037 created 2012/10/11</p>
+<ul>
+<li> Updates the metrics of Majuscule letters in lighter weights.</li>
+<li> Updates fonts to add small capitals and superior capital letters to upright styles.</li>
+<li> Adds the following characters for transliteration: Blinebelow blinebelow</li>
+<li> Klinebelow klinebelow Emacronacute emacronacute Omacronacute omacronacute primemod</li>
+<li> Adds the following punctuation characters: bardbl iterrobang ceilingleft ceilingright </li>
+<li> floorleft floorright bracketleftwhite bracketrightwhite brackhalftopleft </li>
+<li> brackhalftopright brackhalfbotleft brackhalfbotright</li>
+<li> Adds dotted zero and slashed zero.</li>
+</ul>
+<p>version 1.036 created 2012/09/12</p>
+<ul>
+<li> Updates fonts to fix bug in TTF versions in which the GDEF table was not included.</li>
+</ul>
+<p>version 1.035 created 2012/09/10</p>
+<ul>
+<li> Updates the fitting for 'u' and its related glyphs. Updates the kerning in the upright fonts.</li>
+</ul>
+<p>version 1.034 created 2012/08/15</p>
+<ul>
+<li> Improved sidebearings of some glyphs, improved kerning classes, improved some kern pairs.</li>
+<li> Fixed metrics issues with upright letter D and composites.</li>
+<li> Added glyphs and OT feature support for Jarai language.</li>
+<li> Added 'ordfeminine' glyph to 'ss02' feature.</li>
+<li> Changed glyph name 'schwa.supss' to 'uni0259.sups'.</li>
+<li> Changed weightClass value of the ExtraLight fonts from 250 to 200.</li>
+<li> Changed OS/2.usWinAscent and OS/2.usWinDescent values to be the same across all fonts.</li>
+<li> Changed hhea.Ascender and hhea.Descender values as a result of the OS/2usWin changes.</li>
+<li> Changed OS/2 table version number from 4 to 3.</li>
+<li> Harmonized the copyright strings.</li>
+</ul>
+<p>version 1.033 created 2012/07/31</p>
+<ul>
+<li> First release.</li>
+</ul>
+</div>
+ <div id="title">
+ <h2>
+ <a name="A8" id="A8">Known issues</a>
+ </h2>
+ </div>
+ <div id="description"><ul> <li>Some glyphs in the font cannot be accessed unless you are using an OpenType compatible application.
+ </li>
+</ul></div>
+ <div id="title">
+ <h2>
+ <a name="A9" id="A9">Customer care</a>
+ </h2>
+ </div>
+ <div id="description">
+ <p>
+ <strong>Customer Service</strong>
+ <br />Adobe Customer Service provides assistance with product information, sales, registration, and other non-technical issues.
+ To find out how to contact Adobe Customer Service, please visit <a href="http://www.adobe.com">Adobe.com</a> for your region or country and click on Contact Adobe.</p>
+ <p>
+ <strong>Support Plan Options and Technical Resources</strong>
+ <br />If you require technical assistance for your product, including information on free and paid support options and troubleshooting resources, more information is available at
+ <a title="http://www.adobe.com/go/support/" href="http://www.adobe.com/go/support/">
+ <span title="http://www.adobe.com/go/support/">http://www.adobe.com/go/support/.</span>
+ </a> Outside of North America, go to
+ <a title="http://www.adobe.com/go/intlsupport/" href="http://www.adobe.com/go/intlsupport/">
+ <span title="http://www.adobe.com/go/intlsupport/">http://www.adobe.com/go/intlsupport/.</span>
+ </a>Font specific resources include the <a href="http://helpx.adobe.com/font-folio-type.html">Font Folio and Type Product Help page</a> and the <a href="http://forums.adobe.com/community/typography_fonts">Adobe Type user-to-user forums</a>.</p>
+ </div>
+ <div id="title">
+ <h2>
+ <a name="A10" id="A10">Other resources</a>
+ </h2>
+ </div>
+ <div id="description">
+ <p>
+ <a href="http://www.adobe.com/type">Adobe Type Showroom</a>
+ <br />
+ <a href="http://www.adobe.com/type/family_readmes.html">Index page for all family Read Me files</a>
+ <br />
+ </p>
+ <p align="left">
+ <br />
+ Adobe, the Adobe Logo, Source, Illustrator, InDesign, PageMaker and Photoshop are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries. Windows and OpenType are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Mac, Mac OS and TrueType are trademarks of Apple Inc., registered in the U.S. and other countries. All other trademarks are the property of their respective owners. <br />
+ <br />
+ <hFooter>
+ &copy; 2014 Adobe Systems Incorporated. All rights reserved.<br /><br />created 2014 Jun 17
+ <hFooter>
+ </p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/fonts/TTF/SourceSansPro-Black.ttf b/fonts/TTF/SourceSansPro-Black.ttf
new file mode 100755
index 0000000..0243842
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-Black.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-BlackIt.ttf b/fonts/TTF/SourceSansPro-BlackIt.ttf
new file mode 100755
index 0000000..167045f
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-BlackIt.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-Bold.ttf b/fonts/TTF/SourceSansPro-Bold.ttf
new file mode 100755
index 0000000..be46652
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-Bold.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-BoldIt.ttf b/fonts/TTF/SourceSansPro-BoldIt.ttf
new file mode 100755
index 0000000..fd5c4f3
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-BoldIt.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-ExtraLight.ttf b/fonts/TTF/SourceSansPro-ExtraLight.ttf
new file mode 100755
index 0000000..182165c
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-ExtraLight.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-ExtraLightIt.ttf b/fonts/TTF/SourceSansPro-ExtraLightIt.ttf
new file mode 100755
index 0000000..5846588
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-ExtraLightIt.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-It.ttf b/fonts/TTF/SourceSansPro-It.ttf
new file mode 100755
index 0000000..c689cd2
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-It.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-Light.ttf b/fonts/TTF/SourceSansPro-Light.ttf
new file mode 100755
index 0000000..dcff4e9
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-Light.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-LightIt.ttf b/fonts/TTF/SourceSansPro-LightIt.ttf
new file mode 100755
index 0000000..0c3451f
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-LightIt.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-Regular.ttf b/fonts/TTF/SourceSansPro-Regular.ttf
new file mode 100755
index 0000000..a011dff
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-Regular.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-Semibold.ttf b/fonts/TTF/SourceSansPro-Semibold.ttf
new file mode 100755
index 0000000..dbf946a
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-Semibold.ttf
Binary files differ
diff --git a/fonts/TTF/SourceSansPro-SemiboldIt.ttf b/fonts/TTF/SourceSansPro-SemiboldIt.ttf
new file mode 100755
index 0000000..d1bc7f0
--- /dev/null
+++ b/fonts/TTF/SourceSansPro-SemiboldIt.ttf
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-Black.otf.woff b/fonts/WOFF/OTF/SourceSansPro-Black.otf.woff
new file mode 100755
index 0000000..bbc0477
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-Black.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-BlackIt.otf.woff b/fonts/WOFF/OTF/SourceSansPro-BlackIt.otf.woff
new file mode 100755
index 0000000..516e77e
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-BlackIt.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-Bold.otf.woff b/fonts/WOFF/OTF/SourceSansPro-Bold.otf.woff
new file mode 100755
index 0000000..0036a54
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-Bold.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-BoldIt.otf.woff b/fonts/WOFF/OTF/SourceSansPro-BoldIt.otf.woff
new file mode 100755
index 0000000..de03ab7
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-BoldIt.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-ExtraLight.otf.woff b/fonts/WOFF/OTF/SourceSansPro-ExtraLight.otf.woff
new file mode 100755
index 0000000..1ce6f1b
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-ExtraLight.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-ExtraLightIt.otf.woff b/fonts/WOFF/OTF/SourceSansPro-ExtraLightIt.otf.woff
new file mode 100755
index 0000000..d3c21fe
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-ExtraLightIt.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-It.otf.woff b/fonts/WOFF/OTF/SourceSansPro-It.otf.woff
new file mode 100755
index 0000000..9cae9b4
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-It.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-Light.otf.woff b/fonts/WOFF/OTF/SourceSansPro-Light.otf.woff
new file mode 100755
index 0000000..e6c49a7
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-Light.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-LightIt.otf.woff b/fonts/WOFF/OTF/SourceSansPro-LightIt.otf.woff
new file mode 100755
index 0000000..d36baaa
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-LightIt.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-Regular.otf.woff b/fonts/WOFF/OTF/SourceSansPro-Regular.otf.woff
new file mode 100755
index 0000000..6bc912b
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-Regular.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-Semibold.otf.woff b/fonts/WOFF/OTF/SourceSansPro-Semibold.otf.woff
new file mode 100755
index 0000000..475c499
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-Semibold.otf.woff
Binary files differ
diff --git a/fonts/WOFF/OTF/SourceSansPro-SemiboldIt.otf.woff b/fonts/WOFF/OTF/SourceSansPro-SemiboldIt.otf.woff
new file mode 100755
index 0000000..62c2997
--- /dev/null
+++ b/fonts/WOFF/OTF/SourceSansPro-SemiboldIt.otf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-Black.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-Black.ttf.woff
new file mode 100755
index 0000000..b1c446b
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-Black.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-BlackIt.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-BlackIt.ttf.woff
new file mode 100755
index 0000000..e5f876e
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-BlackIt.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-Bold.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-Bold.ttf.woff
new file mode 100755
index 0000000..997f32f
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-Bold.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-BoldIt.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-BoldIt.ttf.woff
new file mode 100755
index 0000000..97e03c4
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-BoldIt.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-ExtraLight.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-ExtraLight.ttf.woff
new file mode 100755
index 0000000..dc349cb
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-ExtraLight.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-ExtraLightIt.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-ExtraLightIt.ttf.woff
new file mode 100755
index 0000000..439189b
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-ExtraLightIt.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-It.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-It.ttf.woff
new file mode 100755
index 0000000..8b412df
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-It.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-Light.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-Light.ttf.woff
new file mode 100755
index 0000000..94dade4
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-Light.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-LightIt.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-LightIt.ttf.woff
new file mode 100755
index 0000000..f4148b4
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-LightIt.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-Regular.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-Regular.ttf.woff
new file mode 100755
index 0000000..3e03cc0
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-Regular.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-Semibold.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-Semibold.ttf.woff
new file mode 100755
index 0000000..f0ac404
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-Semibold.ttf.woff
Binary files differ
diff --git a/fonts/WOFF/TTF/SourceSansPro-SemiboldIt.ttf.woff b/fonts/WOFF/TTF/SourceSansPro-SemiboldIt.ttf.woff
new file mode 100755
index 0000000..f971767
--- /dev/null
+++ b/fonts/WOFF/TTF/SourceSansPro-SemiboldIt.ttf.woff
Binary files differ
diff --git a/fonts/bower.json b/fonts/bower.json
new file mode 100755
index 0000000..08aca6c
--- /dev/null
+++ b/fonts/bower.json
@@ -0,0 +1,17 @@
+{
+ "name": "source-sans-pro",
+ "version": "2.010R-ro/1.065R-it",
+ "main": "source-sans-pro.css",
+ "homepage": "https://github.com/adobe-fonts/source-sans-pro",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/adobe-fonts/source-sans-pro.git"
+ },
+ "authors": [
+ { "name": "Paul D. Hunt" }
+ ],
+ "description": "Source Sans Pro font family by Adobe",
+ "license": "SIL OFL 1.1",
+ "keywords": ["font", "sourcesans", "sourcesanspro", "source sans", "source sans pro"],
+ "ignore": ["**/.*"]
+}
diff --git a/fonts/source-sans-pro.css b/fonts/source-sans-pro.css
new file mode 100755
index 0000000..0a47e9e
--- /dev/null
+++ b/fonts/source-sans-pro.css
@@ -0,0 +1,131 @@
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 200;
+ font-style: normal;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-ExtraLight.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-ExtraLight.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-ExtraLight.otf') format('opentype'),
+ url('TTF/SourceSansPro-ExtraLight.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 200;
+ font-style: italic;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-ExtraLightIt.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-ExtraLightIt.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-ExtraLightIt.otf') format('opentype'),
+ url('TTF/SourceSansPro-ExtraLightIt.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 300;
+ font-style: normal;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-Light.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-Light.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-Light.otf') format('opentype'),
+ url('TTF/SourceSansPro-Light.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 300;
+ font-style: italic;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-LightIt.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-LightIt.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-LightIt.otf') format('opentype'),
+ url('TTF/SourceSansPro-LightIt.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 400;
+ font-style: normal;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-Regular.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-Regular.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-Regular.otf') format('opentype'),
+ url('TTF/SourceSansPro-Regular.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 400;
+ font-style: italic;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-It.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-It.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-It.otf') format('opentype'),
+ url('TTF/SourceSansPro-It.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 600;
+ font-style: normal;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-Semibold.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-Semibold.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-Semibold.otf') format('opentype'),
+ url('TTF/SourceSansPro-Semibold.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 600;
+ font-style: italic;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-SemiboldIt.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-SemiboldIt.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-SemiboldIt.otf') format('opentype'),
+ url('TTF/SourceSansPro-SemiboldIt.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 700;
+ font-style: normal;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-Bold.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-Bold.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-Bold.otf') format('opentype'),
+ url('TTF/SourceSansPro-Bold.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 700;
+ font-style: italic;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-BoldIt.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-BoldIt.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-BoldIt.otf') format('opentype'),
+ url('TTF/SourceSansPro-BoldIt.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 900;
+ font-style: normal;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-Black.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-Black.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-Black.otf') format('opentype'),
+ url('TTF/SourceSansPro-Black.ttf') format('truetype');
+}
+
+@font-face{
+ font-family: 'Source Sans Pro';
+ font-weight: 900;
+ font-style: italic;
+ font-stretch: normal;
+ src: url('EOT/SourceSansPro-BlackIt.eot') format('embedded-opentype'),
+ url('WOFF/OTF/SourceSansPro-BlackIt.otf.woff') format('woff'),
+ url('OTF/SourceSansPro-BlackIt.otf') format('opentype'),
+ url('TTF/SourceSansPro-BlackIt.ttf') format('truetype');
+}
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..047e574
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title>Basic example bog</title>
+ <link rel='stylesheet' href='./css/source-sans-pro.min.css' />
+ <link rel='stylesheet' href='./css/style.css' />
+ </head>
+ <body>
+ <script src="nacl.min.js"></script>
+ <script src="nacl-util.min.js"></script>
+ <script src="lib.js"></script>
+ <script src="app.js"></script>
+ </body>
+</html>
diff --git a/lib.js b/lib.js
new file mode 100644
index 0000000..ce86fc4
--- /dev/null
+++ b/lib.js
@@ -0,0 +1,264 @@
+// generate a public.private keypair with TweetNaCl.js
+
+function getKeys () {
+ if (localStorage['id']) {
+ var keys = JSON.parse(localStorage['id'])
+ return keys
+ } else {
+
+ var genkey = nacl.sign.keyPair()
+ if (genkey) {
+ var keys = {
+ publicKey: '@' + nacl.util.encodeBase64(genkey.publicKey),
+ privateKey: nacl.util.encodeBase64(genkey.secretKey),
+ }
+
+ console.log(genkey)
+ if ((keys.publicKey.includes('+')) || (keys.publicKey.includes('/'))) {
+ console.log('TRYING AGAIN')
+ setTimeout(function () {
+ window.location.reload()
+ }, 100)
+ } else {
+ localStorage['id'] = JSON.stringify(keys)
+ return keys
+ }
+ }
+ }
+}
+
+// publish new messages to your log
+function publish (content, keys) {
+
+ if (localStorage[keys.publicKey]) {
+ var log = JSON.parse(localStorage[keys.publicKey])
+ var lastPost = log[0]
+ var seq = lastPost.content.sequence
+ content.sequence = ++seq
+ content.previous = nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(JSON.stringify(log[0]))))
+ console.log(content.previous)
+ } else {
+ console.log('SEQUENCE 0')
+ content.sequence = 0
+ }
+
+ var post = {
+ content: content,
+ signature: nacl.util.encodeBase64(nacl.sign(nacl.util.decodeUTF8(JSON.stringify(content)), nacl.util.decodeBase64(keys.privateKey)))
+ }
+
+ // add key (which is a hash of the stringified object post)
+ post.key = '%' + nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(JSON.stringify(post))))
+
+ // update the log
+ updateLog(keys.publicKey, post)
+
+ var scroller = document.getElementById('scroller')
+ if (scroller.firstChild) {
+ scroller.insertBefore(renderMessage(post), scroller.childNodes[1])
+ } else {
+ scroller.appendChild(renderMessage(post))
+ }
+}
+
+// update your log in the browser
+
+function updateLog (feed, post) {
+ if (localStorage[feed]) {
+ var log = JSON.parse(localStorage[feed])
+ log.unshift(post)
+ localStorage[feed] = JSON.stringify(log)
+ } else {
+ var log = [post]
+ localStorage[feed] = JSON.stringify(log)
+ }
+
+ if (localStorage['log']) {
+ var log = JSON.parse(localStorage['log'])
+ log.unshift(post)
+ localStorage['log'] = JSON.stringify(log)
+ } else {
+ var log = [post]
+ localStorage['log'] = JSON.stringify(log)
+ }
+}
+
+// file uploaders for user images
+
+function readFile () {
+ if (this.files && this.files[0]) {
+
+ var fr = new FileReader();
+
+ fr.addEventListener("load", function(e) {
+ var image = e.target.result
+ document.getElementById("img").src = e.target.result;
+ document.getElementById("img").style = 'width: 75px; height: 75px';
+ document.getElementById("b64").innerHTML = e.target.result;
+ });
+
+ fr.readAsDataURL( this.files[0] );
+ }
+
+}
+
+
+// render messages
+
+function renderMessage (post) {
+ var message = h('div', {classList: 'message'})
+
+ if (post.content.type == 'name') {
+ var mini = h('span', [
+ ' identified as ',
+ post.content.text
+ ])
+
+ message.appendChild(getHeader(post, mini))
+ //message.appendChild(h('pre', [JSON.stringify(post)]))
+ }
+
+ if (post.content.type == 'image') {
+
+ var mini = h('span', [
+ ' identified as ',
+ h('img', {classList: 'small', src:post.content.image})
+ ])
+
+ message.appendChild(getHeader(post, mini))
+ //message.appendChild(h('pre', [JSON.stringify(post)]))
+ }
+
+ if (post.content.type == 'post') {
+
+
+ message.appendChild(getHeader(post))
+ message.appendChild(h('div', [post.content.text]))
+ message.appendChild(h('pre', [JSON.stringify(post)]))
+
+ var textarea = h('textarea', {placeholder: 'Reply to this bog post'})
+
+ message.appendChild(h('button', {
+ onclick: function () {
+ message.appendChild(textarea)
+ message.appendChild(h('button', {
+ onclick: function () {
+ if (textarea.value) {
+ var content = {
+ author: keys.publicKey,
+ type: 'post',
+ text: textarea.value,
+ reply: post.key,
+ timestamp: Date.now()
+ }
+ console.log(content)
+ publish(content, keys)
+ }
+ }
+ }, ['Publish']))
+
+ }
+ }, ['Reply']))
+
+
+ }
+
+ return message
+}
+
+
+function getImage (id) {
+ var image = h('img', {classList: 'small'})
+
+ if (localStorage[id]) {
+ var log = JSON.parse(localStorage[id])
+ for (var i=0; i < log.length; i++) {
+ var imagePost = log[i]
+ if (imagePost.content.type == 'image') {
+ image = h('img', {classList: 'small', src: imagePost.content.image})
+ return image
+ }
+ }
+ }
+
+ return image
+}
+
+function getName (id) {
+ var name = h('span', [id])
+ if (localStorage[id]) {
+ var log = JSON.parse(localStorage[id])
+ for (var i=0; i < log.length; i++) {
+ var namePost = log[i]
+ if (namePost.content.type == 'name') {
+ name = h('span', ['@' + namePost.content.text])
+ return name
+ }
+ }
+ }
+ return name
+}
+
+function getHeader (post, mini) {
+ var inner
+ if (mini) {
+ var inner = mini
+ }
+
+ var head = h('span', [
+ h('a', {href: '#' + post.key}, [
+ h('p', {classList: 'right'}, [human(new Date(post.content.timestamp))]),
+ ]),
+ h('p', [
+ h('a', {href: '#' + post.content.author}, [
+ getImage(post.content.author),
+ getName(post.content.author)
+ ]),
+ inner
+ ])
+ ])
+ return head
+}
+
+// human-time by Dave Eddy https://github.com/bahamas10/human
+
+function human(seconds) {
+ if (seconds instanceof Date)
+ seconds = Math.round((Date.now() - seconds) / 1000);
+ var suffix = seconds < 0 ? 'from now' : 'ago';
+ seconds = Math.abs(seconds);
+
+ var times = [
+ seconds / 60 / 60 / 24 / 365, // years
+ seconds / 60 / 60 / 24 / 30, // months
+ seconds / 60 / 60 / 24 / 7, // weeks
+ seconds / 60 / 60 / 24, // days
+ seconds / 60 / 60, // hours
+ seconds / 60, // minutes
+ seconds // seconds
+ ];
+ var names = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second'];
+
+ for (var i = 0; i < names.length; i++) {
+ var time = Math.floor(times[i]);
+ var name = names[i];
+ if (time > 1)
+ name += 's';
+
+ if (time >= 1)
+ return time + ' ' + name + ' ' + suffix;
+ }
+ return '0 seconds ' + suffix;
+}
+
+// hscrpt by Dominic Tarr https://github.com/dominictarr/hscrpt/blob/master/LICENSE
+function h (tag, attrs, content) {
+ if(Array.isArray(attrs)) content = attrs, attrs = {}
+ var el = document.createElement(tag)
+ for(var k in attrs) el[k] = attrs[k]
+ if(content) content.forEach(function (e) {
+ if(e) el.appendChild('string' == typeof e ? document.createTextNode(e) : e)
+ })
+ return el
+}
+
diff --git a/nacl-util.min.js b/nacl-util.min.js
new file mode 100644
index 0000000..0867ece
--- /dev/null
+++ b/nacl-util.min.js
@@ -0,0 +1 @@
+!function(e,n){"use strict";"undefined"!=typeof module&&module.exports?module.exports=n():e.nacl?e.nacl.util=n():(e.nacl={},e.nacl.util=n())}(this,function(){"use strict";function e(e){if(!/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/.test(e))throw new TypeError("invalid encoding")}var n={};return n.decodeUTF8=function(e){if("string"!=typeof e)throw new TypeError("expected string");var n,r=unescape(encodeURIComponent(e)),t=new Uint8Array(r.length);for(n=0;n<r.length;n++)t[n]=r.charCodeAt(n);return t},n.encodeUTF8=function(e){var n,r=[];for(n=0;n<e.length;n++)r.push(String.fromCharCode(e[n]));return decodeURIComponent(escape(r.join("")))},"undefined"==typeof atob?"undefined"!=typeof Buffer.from?(n.encodeBase64=function(e){return Buffer.from(e).toString("base64")},n.decodeBase64=function(n){return e(n),new Uint8Array(Array.prototype.slice.call(Buffer.from(n,"base64"),0))}):(n.encodeBase64=function(e){return new Buffer(e).toString("base64")},n.decodeBase64=function(n){return e(n),new Uint8Array(Array.prototype.slice.call(new Buffer(n,"base64"),0))}):(n.encodeBase64=function(e){var n,r=[],t=e.length;for(n=0;n<t;n++)r.push(String.fromCharCode(e[n]));return btoa(r.join(""))},n.decodeBase64=function(n){e(n);var r,t=atob(n),o=new Uint8Array(t.length);for(r=0;r<t.length;r++)o[r]=t.charCodeAt(r);return o}),n}); \ No newline at end of file
diff --git a/nacl.min.js b/nacl.min.js
new file mode 100644
index 0000000..e4c9bb2
--- /dev/null
+++ b/nacl.min.js
@@ -0,0 +1 @@
+!function(r){"use strict";function n(r,n){return r<<n|r>>>32-n}function e(r,n){var e=255&r[n+3];return e=e<<8|255&r[n+2],(e=e<<8|255&r[n+1])<<8|255&r[n+0]}function t(r,n){var e=r[n]<<24|r[n+1]<<16|r[n+2]<<8|r[n+3],t=r[n+4]<<24|r[n+5]<<16|r[n+6]<<8|r[n+7];return new sr(e,t)}function o(r,n,e){var t;for(t=0;t<4;t++)r[n+t]=255&e,e>>>=8}function i(r,n,e){r[n]=e.hi>>24&255,r[n+1]=e.hi>>16&255,r[n+2]=e.hi>>8&255,r[n+3]=255&e.hi,r[n+4]=e.lo>>24&255,r[n+5]=e.lo>>16&255,r[n+6]=e.lo>>8&255,r[n+7]=255&e.lo}function f(r,n,e,t,o){var i,f=0;for(i=0;i<o;i++)f|=r[n+i]^e[t+i];return(1&f-1>>>8)-1}function a(r,n,e,t){return f(r,n,e,t,16)}function u(r,n,e,t){return f(r,n,e,t,32)}function c(r,t,i,f,a){var u,c,w,y=new Uint32Array(16),l=new Uint32Array(16),s=new Uint32Array(16),h=new Uint32Array(4);for(u=0;u<4;u++)l[5*u]=e(f,4*u),l[1+u]=e(i,4*u),l[6+u]=e(t,4*u),l[11+u]=e(i,16+4*u);for(u=0;u<16;u++)s[u]=l[u];for(u=0;u<20;u++){for(c=0;c<4;c++){for(w=0;w<4;w++)h[w]=l[(5*c+4*w)%16];for(h[1]^=n(h[0]+h[3]|0,7),h[2]^=n(h[1]+h[0]|0,9),h[3]^=n(h[2]+h[1]|0,13),h[0]^=n(h[3]+h[2]|0,18),w=0;w<4;w++)y[4*c+(c+w)%4]=h[w]}for(w=0;w<16;w++)l[w]=y[w]}if(a){for(u=0;u<16;u++)l[u]=l[u]+s[u]|0;for(u=0;u<4;u++)l[5*u]=l[5*u]-e(f,4*u)|0,l[6+u]=l[6+u]-e(t,4*u)|0;for(u=0;u<4;u++)o(r,4*u,l[5*u]),o(r,16+4*u,l[6+u])}else for(u=0;u<16;u++)o(r,4*u,l[u]+s[u]|0)}function w(r,n,e,t){return c(r,n,e,t,!1),0}function y(r,n,e,t){return c(r,n,e,t,!0),0}function l(r,n,e,t,o,i,f){var a,u,c=new Uint8Array(16),y=new Uint8Array(64);if(!o)return 0;for(u=0;u<16;u++)c[u]=0;for(u=0;u<8;u++)c[u]=i[u];for(;o>=64;){for(w(y,c,f,Br),u=0;u<64;u++)r[n+u]=(e?e[t+u]:0)^y[u];for(a=1,u=8;u<16;u++)a=a+(255&c[u])|0,c[u]=255&a,a>>>=8;o-=64,n+=64,e&&(t+=64)}if(o>0)for(w(y,c,f,Br),u=0;u<o;u++)r[n+u]=(e?e[t+u]:0)^y[u];return 0}function s(r,n,e,t,o){return l(r,n,null,0,e,t,o)}function h(r,n,e,t,o){var i=new Uint8Array(32);return y(i,t,o,Br),s(r,n,e,t.subarray(16),i)}function v(r,n,e,t,o,i,f){var a=new Uint8Array(32);return y(a,i,f,Br),l(r,n,e,t,o,i.subarray(16),a)}function g(r,n){var e,t=0;for(e=0;e<17;e++)t=t+(r[e]+n[e]|0)|0,r[e]=255&t,t>>>=8}function b(r,n,e,t,o,i){var f,a,u,c,w=new Uint32Array(17),y=new Uint32Array(17),l=new Uint32Array(17),s=new Uint32Array(17),h=new Uint32Array(17);for(u=0;u<17;u++)y[u]=l[u]=0;for(u=0;u<16;u++)y[u]=i[u];for(y[3]&=15,y[4]&=252,y[7]&=15,y[8]&=252,y[11]&=15,y[12]&=252,y[15]&=15;o>0;){for(u=0;u<17;u++)s[u]=0;for(u=0;u<16&&u<o;++u)s[u]=e[t+u];for(s[u]=1,t+=u,o-=u,g(l,s),a=0;a<17;a++)for(w[a]=0,u=0;u<17;u++)w[a]=0|w[a]+l[u]*(u<=a?y[a-u]:320*y[a+17-u]|0);for(a=0;a<17;a++)l[a]=w[a];for(c=0,u=0;u<16;u++)c=c+l[u]|0,l[u]=255&c,c>>>=8;for(c=c+l[16]|0,l[16]=3&c,c=5*(c>>>2)|0,u=0;u<16;u++)c=c+l[u]|0,l[u]=255&c,c>>>=8;c=c+l[16]|0,l[16]=c}for(u=0;u<17;u++)h[u]=l[u];for(g(l,Sr),f=0|-(l[16]>>>7),u=0;u<17;u++)l[u]^=f&(h[u]^l[u]);for(u=0;u<16;u++)s[u]=i[u+16];for(s[16]=0,g(l,s),u=0;u<16;u++)r[n+u]=l[u];return 0}function p(r,n,e,t,o,i){var f=new Uint8Array(16);return b(f,0,e,t,o,i),a(r,n,f,0)}function _(r,n,e,t,o){var i;if(e<32)return-1;for(v(r,0,n,0,e,t,o),b(r,16,r,32,e-32,r),i=0;i<16;i++)r[i]=0;return 0}function A(r,n,e,t,o){var i,f=new Uint8Array(32);if(e<32)return-1;if(h(f,0,32,t,o),0!==p(n,16,n,32,e-32,f))return-1;for(v(r,0,n,0,e,t,o),i=0;i<32;i++)r[i]=0;return 0}function U(r,n){var e;for(e=0;e<16;e++)r[e]=0|n[e]}function E(r){var n,e;for(e=0;e<16;e++)r[e]+=65536,n=Math.floor(r[e]/65536),r[(e+1)*(e<15?1:0)]+=n-1+37*(n-1)*(15===e?1:0),r[e]-=65536*n}function x(r,n,e){for(var t,o=~(e-1),i=0;i<16;i++)t=o&(r[i]^n[i]),r[i]^=t,n[i]^=t}function d(r,n){var e,t,o,i=hr(),f=hr();for(e=0;e<16;e++)f[e]=n[e];for(E(f),E(f),E(f),t=0;t<2;t++){for(i[0]=f[0]-65517,e=1;e<15;e++)i[e]=f[e]-65535-(i[e-1]>>16&1),i[e-1]&=65535;i[15]=f[15]-32767-(i[14]>>16&1),o=i[15]>>16&1,i[14]&=65535,x(f,i,1-o)}for(e=0;e<16;e++)r[2*e]=255&f[e],r[2*e+1]=f[e]>>8}function m(r,n){var e=new Uint8Array(32),t=new Uint8Array(32);return d(e,r),d(t,n),u(e,0,t,0)}function B(r){var n=new Uint8Array(32);return d(n,r),1&n[0]}function S(r,n){var e;for(e=0;e<16;e++)r[e]=n[2*e]+(n[2*e+1]<<8);r[15]&=32767}function K(r,n,e){var t;for(t=0;t<16;t++)r[t]=n[t]+e[t]|0}function Y(r,n,e){var t;for(t=0;t<16;t++)r[t]=n[t]-e[t]|0}function T(r,n,e){var t,o,i=new Float64Array(31);for(t=0;t<31;t++)i[t]=0;for(t=0;t<16;t++)for(o=0;o<16;o++)i[t+o]+=n[t]*e[o];for(t=0;t<15;t++)i[t]+=38*i[t+16];for(t=0;t<16;t++)r[t]=i[t];E(r),E(r)}function L(r,n){T(r,n,n)}function k(r,n){var e,t=hr();for(e=0;e<16;e++)t[e]=n[e];for(e=253;e>=0;e--)L(t,t),2!==e&&4!==e&&T(t,t,n);for(e=0;e<16;e++)r[e]=t[e]}function z(r,n){var e,t=hr();for(e=0;e<16;e++)t[e]=n[e];for(e=250;e>=0;e--)L(t,t),1!==e&&T(t,t,n);for(e=0;e<16;e++)r[e]=t[e]}function R(r,n,e){var t,o,i=new Uint8Array(32),f=new Float64Array(80),a=hr(),u=hr(),c=hr(),w=hr(),y=hr(),l=hr();for(o=0;o<31;o++)i[o]=n[o];for(i[31]=127&n[31]|64,i[0]&=248,S(f,e),o=0;o<16;o++)u[o]=f[o],w[o]=a[o]=c[o]=0;for(a[0]=w[0]=1,o=254;o>=0;--o)t=i[o>>>3]>>>(7&o)&1,x(a,u,t),x(c,w,t),K(y,a,c),Y(a,a,c),K(c,u,w),Y(u,u,w),L(w,y),L(l,a),T(a,c,a),T(c,u,y),K(y,a,c),Y(a,a,c),L(u,a),Y(c,w,l),T(a,c,Ar),K(a,a,w),T(c,c,a),T(a,w,l),T(w,u,f),L(u,y),x(a,u,t),x(c,w,t);for(o=0;o<16;o++)f[o+16]=a[o],f[o+32]=c[o],f[o+48]=u[o],f[o+64]=w[o];var s=f.subarray(32),h=f.subarray(16);return k(s,s),T(h,h,s),d(r,h),0}function P(r,n){return R(r,n,br)}function N(r,n){return vr(n,32),P(r,n)}function O(r,n,e){var t=new Uint8Array(32);return R(t,e,n),y(r,gr,t,Br)}function C(r,n,e,t,o,i){var f=new Uint8Array(32);return O(f,o,i),Kr(r,n,e,t,f)}function F(r,n,e,t,o,i){var f=new Uint8Array(32);return O(f,o,i),Yr(r,n,e,t,f)}function M(){var r,n,e,t=0,o=0,i=0,f=0;for(e=0;e<arguments.length;e++)r=arguments[e].lo,n=arguments[e].hi,t+=65535&r,o+=r>>>16,i+=65535&n,f+=n>>>16;return o+=t>>>16,i+=o>>>16,f+=i>>>16,new sr(65535&i|f<<16,65535&t|o<<16)}function G(r,n){return new sr(r.hi>>>n,r.lo>>>n|r.hi<<32-n)}function Z(){var r,n=0,e=0;for(r=0;r<arguments.length;r++)n^=arguments[r].lo,e^=arguments[r].hi;return new sr(e,n)}function q(r,n){var e,t,o=32-n;return n<32?(e=r.hi>>>n|r.lo<<o,t=r.lo>>>n|r.hi<<o):n<64&&(e=r.lo>>>n|r.hi<<o,t=r.hi>>>n|r.lo<<o),new sr(e,t)}function I(r,n,e){var t=r.hi&n.hi^~r.hi&e.hi,o=r.lo&n.lo^~r.lo&e.lo;return new sr(t,o)}function V(r,n,e){var t=r.hi&n.hi^r.hi&e.hi^n.hi&e.hi,o=r.lo&n.lo^r.lo&e.lo^n.lo&e.lo;return new sr(t,o)}function X(r){return Z(q(r,28),q(r,34),q(r,39))}function D(r){return Z(q(r,14),q(r,18),q(r,41))}function j(r){return Z(q(r,1),q(r,8),G(r,7))}function H(r){return Z(q(r,19),q(r,61),G(r,6))}function J(r,n,e){var o,f,a,u=[],c=[],w=[],y=[];for(f=0;f<8;f++)u[f]=w[f]=t(r,8*f);for(var l=0;e>=128;){for(f=0;f<16;f++)y[f]=t(n,8*f+l);for(f=0;f<80;f++){for(a=0;a<8;a++)c[a]=w[a];for(o=M(w[7],D(w[4]),I(w[4],w[5],w[6]),Tr[f],y[f%16]),c[7]=M(o,X(w[0]),V(w[0],w[1],w[2])),c[3]=M(c[3],o),a=0;a<8;a++)w[(a+1)%8]=c[a];if(f%16==15)for(a=0;a<16;a++)y[a]=M(y[a],y[(a+9)%16],j(y[(a+1)%16]),H(y[(a+14)%16]))}for(f=0;f<8;f++)w[f]=M(w[f],u[f]),u[f]=w[f];l+=128,e-=128}for(f=0;f<8;f++)i(r,8*f,u[f]);return e}function Q(r,n,e){var t,o=new Uint8Array(64),f=new Uint8Array(256),a=e;for(t=0;t<64;t++)o[t]=Lr[t];for(J(o,n,e),e%=128,t=0;t<256;t++)f[t]=0;for(t=0;t<e;t++)f[t]=n[a-e+t];for(f[e]=128,e=256-128*(e<112?1:0),f[e-9]=0,i(f,e-8,new sr(a/536870912|0,a<<3)),J(o,f,e),t=0;t<64;t++)r[t]=o[t];return 0}function W(r,n){var e=hr(),t=hr(),o=hr(),i=hr(),f=hr(),a=hr(),u=hr(),c=hr(),w=hr();Y(e,r[1],r[0]),Y(w,n[1],n[0]),T(e,e,w),K(t,r[0],r[1]),K(w,n[0],n[1]),T(t,t,w),T(o,r[3],n[3]),T(o,o,Er),T(i,r[2],n[2]),K(i,i,i),Y(f,t,e),Y(a,i,o),K(u,i,o),K(c,t,e),T(r[0],f,a),T(r[1],c,u),T(r[2],u,a),T(r[3],f,c)}function $(r,n,e){var t;for(t=0;t<4;t++)x(r[t],n[t],e)}function rr(r,n){var e=hr(),t=hr(),o=hr();k(o,n[2]),T(e,n[0],o),T(t,n[1],o),d(r,t),r[31]^=B(e)<<7}function nr(r,n,e){var t,o;for(U(r[0],pr),U(r[1],_r),U(r[2],_r),U(r[3],pr),o=255;o>=0;--o)t=e[o/8|0]>>(7&o)&1,$(r,n,t),W(n,r),W(r,r),$(r,n,t)}function er(r,n){var e=[hr(),hr(),hr(),hr()];U(e[0],xr),U(e[1],dr),U(e[2],_r),T(e[3],xr,dr),nr(r,e,n)}function tr(r,n,e){var t,o=new Uint8Array(64),i=[hr(),hr(),hr(),hr()];for(e||vr(n,32),Q(o,n,32),o[0]&=248,o[31]&=127,o[31]|=64,er(i,o),rr(r,i),t=0;t<32;t++)n[t+32]=r[t];return 0}function or(r,n){var e,t,o,i;for(t=63;t>=32;--t){for(e=0,o=t-32,i=t-12;o<i;++o)n[o]+=e-16*n[t]*kr[o-(t-32)],e=n[o]+128>>8,n[o]-=256*e;n[o]+=e,n[t]=0}for(e=0,o=0;o<32;o++)n[o]+=e-(n[31]>>4)*kr[o],e=n[o]>>8,n[o]&=255;for(o=0;o<32;o++)n[o]-=e*kr[o];for(t=0;t<32;t++)n[t+1]+=n[t]>>8,r[t]=255&n[t]}function ir(r){var n,e=new Float64Array(64);for(n=0;n<64;n++)e[n]=r[n];for(n=0;n<64;n++)r[n]=0;or(r,e)}function fr(r,n,e,t){var o,i,f=new Uint8Array(64),a=new Uint8Array(64),u=new Uint8Array(64),c=new Float64Array(64),w=[hr(),hr(),hr(),hr()];Q(f,t,32),f[0]&=248,f[31]&=127,f[31]|=64;var y=e+64;for(o=0;o<e;o++)r[64+o]=n[o];for(o=0;o<32;o++)r[32+o]=f[32+o];for(Q(u,r.subarray(32),e+32),ir(u),er(w,u),rr(r,w),o=32;o<64;o++)r[o]=t[o];for(Q(a,r,e+64),ir(a),o=0;o<64;o++)c[o]=0;for(o=0;o<32;o++)c[o]=u[o];for(o=0;o<32;o++)for(i=0;i<32;i++)c[o+i]+=a[o]*f[i];return or(r.subarray(32),c),y}function ar(r,n){var e=hr(),t=hr(),o=hr(),i=hr(),f=hr(),a=hr(),u=hr();return U(r[2],_r),S(r[1],n),L(o,r[1]),T(i,o,Ur),Y(o,o,r[2]),K(i,r[2],i),L(f,i),L(a,f),T(u,a,f),T(e,u,o),T(e,e,i),z(e,e),T(e,e,o),T(e,e,i),T(e,e,i),T(r[0],e,i),L(t,r[0]),T(t,t,i),m(t,o)&&T(r[0],r[0],mr),L(t,r[0]),T(t,t,i),m(t,o)?-1:(B(r[0])===n[31]>>7&&Y(r[0],pr,r[0]),T(r[3],r[0],r[1]),0)}function ur(r,n,e,t){var o,i=new Uint8Array(32),f=new Uint8Array(64),a=[hr(),hr(),hr(),hr()],c=[hr(),hr(),hr(),hr()];if(-1,e<64)return-1;if(ar(c,t))return-1;for(o=0;o<e;o++)r[o]=n[o];for(o=0;o<32;o++)r[o+32]=t[o];if(Q(f,r,e),ir(f),nr(a,c,f),er(c,n.subarray(32)),W(a,c),rr(i,a),e-=64,u(n,0,i,0)){for(o=0;o<e;o++)r[o]=0;return-1}for(o=0;o<e;o++)r[o]=n[o+64];return e}function cr(r,n){if(r.length!==zr)throw new Error("bad key size");if(n.length!==Rr)throw new Error("bad nonce size")}function wr(r,n){if(r.length!==Pr)throw new Error("bad public key size");if(n.length!==Nr)throw new Error("bad secret key size")}function yr(){for(var r=0;r<arguments.length;r++)if(!(arguments[r]instanceof Uint8Array))throw new TypeError("unexpected type, use Uint8Array")}function lr(r){for(var n=0;n<r.length;n++)r[n]=0}var sr=function(r,n){this.hi=0|r,this.lo=0|n},hr=function(r){var n,e=new Float64Array(16);if(r)for(n=0;n<r.length;n++)e[n]=r[n];return e},vr=function(){throw new Error("no PRNG")},gr=new Uint8Array(16),br=new Uint8Array(32);br[0]=9;var pr=hr(),_r=hr([1]),Ar=hr([56129,1]),Ur=hr([30883,4953,19914,30187,55467,16705,2637,112,59544,30585,16505,36039,65139,11119,27886,20995]),Er=hr([61785,9906,39828,60374,45398,33411,5274,224,53552,61171,33010,6542,64743,22239,55772,9222]),xr=hr([54554,36645,11616,51542,42930,38181,51040,26924,56412,64982,57905,49316,21502,52590,14035,8553]),dr=hr([26200,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214,26214]),mr=hr([41136,18958,6951,50414,58488,44335,6150,12099,55207,15867,153,11085,57099,20417,9344,11139]),Br=new Uint8Array([101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107]),Sr=new Uint32Array([5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252]),Kr=_,Yr=A,Tr=[new sr(1116352408,3609767458),new sr(1899447441,602891725),new sr(3049323471,3964484399),new sr(3921009573,2173295548),new sr(961987163,4081628472),new sr(1508970993,3053834265),new sr(2453635748,2937671579),new sr(2870763221,3664609560),new sr(3624381080,2734883394),new sr(310598401,1164996542),new sr(607225278,1323610764),new sr(1426881987,3590304994),new sr(1925078388,4068182383),new sr(2162078206,991336113),new sr(2614888103,633803317),new sr(3248222580,3479774868),new sr(3835390401,2666613458),new sr(4022224774,944711139),new sr(264347078,2341262773),new sr(604807628,2007800933),new sr(770255983,1495990901),new sr(1249150122,1856431235),new sr(1555081692,3175218132),new sr(1996064986,2198950837),new sr(2554220882,3999719339),new sr(2821834349,766784016),new sr(2952996808,2566594879),new sr(3210313671,3203337956),new sr(3336571891,1034457026),new sr(3584528711,2466948901),new sr(113926993,3758326383),new sr(338241895,168717936),new sr(666307205,1188179964),new sr(773529912,1546045734),new sr(1294757372,1522805485),new sr(1396182291,2643833823),new sr(1695183700,2343527390),new sr(1986661051,1014477480),new sr(2177026350,1206759142),new sr(2456956037,344077627),new sr(2730485921,1290863460),new sr(2820302411,3158454273),new sr(3259730800,3505952657),new sr(3345764771,106217008),new sr(3516065817,3606008344),new sr(3600352804,1432725776),new sr(4094571909,1467031594),new sr(275423344,851169720),new sr(430227734,3100823752),new sr(506948616,1363258195),new sr(659060556,3750685593),new sr(883997877,3785050280),new sr(958139571,3318307427),new sr(1322822218,3812723403),new sr(1537002063,2003034995),new sr(1747873779,3602036899),new sr(1955562222,1575990012),new sr(2024104815,1125592928),new sr(2227730452,2716904306),new sr(2361852424,442776044),new sr(2428436474,593698344),new sr(2756734187,3733110249),new sr(3204031479,2999351573),new sr(3329325298,3815920427),new sr(3391569614,3928383900),new sr(3515267271,566280711),new sr(3940187606,3454069534),new sr(4118630271,4000239992),new sr(116418474,1914138554),new sr(174292421,2731055270),new sr(289380356,3203993006),new sr(460393269,320620315),new sr(685471733,587496836),new sr(852142971,1086792851),new sr(1017036298,365543100),new sr(1126000580,2618297676),new sr(1288033470,3409855158),new sr(1501505948,4234509866),new sr(1607167915,987167468),new sr(1816402316,1246189591)],Lr=new Uint8Array([106,9,230,103,243,188,201,8,187,103,174,133,132,202,167,59,60,110,243,114,254,148,248,43,165,79,245,58,95,29,54,241,81,14,82,127,173,230,130,209,155,5,104,140,43,62,108,31,31,131,217,171,251,65,189,107,91,224,205,25,19,126,33,121]),kr=new Float64Array([237,211,245,92,26,99,18,88,214,156,247,162,222,249,222,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16]),zr=32,Rr=24,Pr=32,Nr=32,Or=Rr;r.lowlevel={crypto_core_hsalsa20:y,crypto_stream_xor:v,crypto_stream:h,crypto_stream_salsa20_xor:l,crypto_stream_salsa20:s,crypto_onetimeauth:b,crypto_onetimeauth_verify:p,crypto_verify_16:a,crypto_verify_32:u,crypto_secretbox:_,crypto_secretbox_open:A,crypto_scalarmult:R,crypto_scalarmult_base:P,crypto_box_beforenm:O,crypto_box_afternm:Kr,crypto_box:C,crypto_box_open:F,crypto_box_keypair:N,crypto_hash:Q,crypto_sign:fr,crypto_sign_keypair:tr,crypto_sign_open:ur,crypto_secretbox_KEYBYTES:zr,crypto_secretbox_NONCEBYTES:Rr,crypto_secretbox_ZEROBYTES:32,crypto_secretbox_BOXZEROBYTES:16,crypto_scalarmult_BYTES:32,crypto_scalarmult_SCALARBYTES:32,crypto_box_PUBLICKEYBYTES:Pr,crypto_box_SECRETKEYBYTES:Nr,crypto_box_BEFORENMBYTES:32,crypto_box_NONCEBYTES:Or,crypto_box_ZEROBYTES:32,crypto_box_BOXZEROBYTES:16,crypto_sign_BYTES:64,crypto_sign_PUBLICKEYBYTES:32,crypto_sign_SECRETKEYBYTES:64,crypto_sign_SEEDBYTES:32,crypto_hash_BYTES:64},r.randomBytes=function(r){var n=new Uint8Array(r);return vr(n,r),n},r.secretbox=function(r,n,e){yr(r,n,e),cr(e,n);for(var t=new Uint8Array(32+r.length),o=new Uint8Array(t.length),i=0;i<r.length;i++)t[i+32]=r[i];return _(o,t,t.length,n,e),o.subarray(16)},r.secretbox.open=function(r,n,e){yr(r,n,e),cr(e,n);for(var t=new Uint8Array(16+r.length),o=new Uint8Array(t.length),i=0;i<r.length;i++)t[i+16]=r[i];return t.length<32?null:0!==A(o,t,t.length,n,e)?null:o.subarray(32)},r.secretbox.keyLength=zr,r.secretbox.nonceLength=Rr,r.secretbox.overheadLength=16,r.scalarMult=function(r,n){if(yr(r,n),32!==r.length)throw new Error("bad n size");if(32!==n.length)throw new Error("bad p size");var e=new Uint8Array(32);return R(e,r,n),e},r.scalarMult.base=function(r){if(yr(r),32!==r.length)throw new Error("bad n size");var n=new Uint8Array(32);return P(n,r),n},r.scalarMult.scalarLength=32,r.scalarMult.groupElementLength=32,r.box=function(n,e,t,o){var i=r.box.before(t,o);return r.secretbox(n,e,i)},r.box.before=function(r,n){yr(r,n),wr(r,n);var e=new Uint8Array(32);return O(e,r,n),e},r.box.after=r.secretbox,r.box.open=function(n,e,t,o){var i=r.box.before(t,o);return r.secretbox.open(n,e,i)},r.box.open.after=r.secretbox.open,r.box.keyPair=function(){var r=new Uint8Array(Pr),n=new Uint8Array(Nr);return N(r,n),{publicKey:r,secretKey:n}},r.box.keyPair.fromSecretKey=function(r){if(yr(r),r.length!==Nr)throw new Error("bad secret key size");var n=new Uint8Array(Pr);return P(n,r),{publicKey:n,secretKey:new Uint8Array(r)}},r.box.publicKeyLength=Pr,r.box.secretKeyLength=Nr,r.box.sharedKeyLength=32,r.box.nonceLength=Or,r.box.overheadLength=r.secretbox.overheadLength,r.sign=function(r,n){if(yr(r,n),64!==n.length)throw new Error("bad secret key size");var e=new Uint8Array(64+r.length);return fr(e,r,r.length,n),e},r.sign.open=function(r,n){if(yr(r,n),32!==n.length)throw new Error("bad public key size");var e=new Uint8Array(r.length),t=ur(e,r,r.length,n);if(t<0)return null;for(var o=new Uint8Array(t),i=0;i<o.length;i++)o[i]=e[i];return o},r.sign.detached=function(n,e){for(var t=r.sign(n,e),o=new Uint8Array(64),i=0;i<o.length;i++)o[i]=t[i];return o},r.sign.detached.verify=function(r,n,e){if(yr(r,n,e),64!==n.length)throw new Error("bad signature size");if(32!==e.length)throw new Error("bad public key size");var t,o=new Uint8Array(64+r.length),i=new Uint8Array(64+r.length);for(t=0;t<64;t++)o[t]=n[t];for(t=0;t<r.length;t++)o[t+64]=r[t];return ur(i,o,o.length,e)>=0},r.sign.keyPair=function(){var r=new Uint8Array(32),n=new Uint8Array(64);return tr(r,n),{publicKey:r,secretKey:n}},r.sign.keyPair.fromSecretKey=function(r){if(yr(r),64!==r.length)throw new Error("bad secret key size");for(var n=new Uint8Array(32),e=0;e<n.length;e++)n[e]=r[32+e];return{publicKey:n,secretKey:new Uint8Array(r)}},r.sign.keyPair.fromSeed=function(r){if(yr(r),32!==r.length)throw new Error("bad seed size");for(var n=new Uint8Array(32),e=new Uint8Array(64),t=0;t<32;t++)e[t]=r[t];return tr(n,e,!0),{publicKey:n,secretKey:e}},r.sign.publicKeyLength=32,r.sign.secretKeyLength=64,r.sign.seedLength=32,r.sign.signatureLength=64,r.hash=function(r){yr(r);var n=new Uint8Array(64);return Q(n,r,r.length),n},r.hash.hashLength=64,r.verify=function(r,n){return yr(r,n),0!==r.length&&0!==n.length&&(r.length===n.length&&0===f(r,0,n,0,r.length))},r.setPRNG=function(r){vr=r},function(){var n="undefined"!=typeof self?self.crypto||self.msCrypto:null;if(n&&n.getRandomValues){r.setPRNG(function(r,e){var t,o=new Uint8Array(e);for(t=0;t<e;t+=65536)n.getRandomValues(o.subarray(t,t+Math.min(e-t,65536)));for(t=0;t<e;t++)r[t]=o[t];lr(o)})}else"undefined"!=typeof require&&(n=require("crypto"))&&n.randomBytes&&r.setPRNG(function(r,e){var t,o=n.randomBytes(e);for(t=0;t<e;t++)r[t]=o[t];lr(o)})}()}("undefined"!=typeof module&&module.exports?module.exports:self.nacl=self.nacl||{}); \ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..3dfc515
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,65 @@
+{
+ "name": "bogbook",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "async-limiter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+ "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
+ },
+ "ecstatic": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.1.tgz",
+ "integrity": "sha512-/rrctvxZ78HMI/tPIsqdvFKHHscxR3IJuKrZI2ZoUgkt2SiufyLFBmcco+aqQBIu6P1qBsUNG3drAAGLx80vTQ==",
+ "requires": {
+ "he": "^1.1.1",
+ "mime": "^1.6.0",
+ "minimist": "^1.1.0",
+ "url-join": "^2.0.5"
+ }
+ },
+ "he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ },
+ "opn": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz",
+ "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==",
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
+ },
+ "url-join": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz",
+ "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg="
+ },
+ "ws": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+ "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..42d3dcc
--- /dev/null
+++ b/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "bogbook",
+ "version": "1.0.0",
+ "description": "secure blockchain logging (blogging, without the l) -- bogging",
+ "main": "server.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "start": "node server.js"
+ },
+ "author": "Ev Bogue <ev@evbogue.com>",
+ "license": "MIT",
+ "dependencies": {
+ "ecstatic": "^3.3.1",
+ "opn": "^6.0.0",
+ "ws": "^6.2.1"
+ }
+}
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..d3244c7
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,65 @@
+# bogbook
+
+### secure blockchain logging (blogging).
+
+To avoid confusion we're dropping the 'l' and calling them 'bogs'.
+
+**WARNING** This is very new and experimental software, **not intended for use in production**. Pull-requests are welcome, and if you find anything wrong feel free to report it in public.
+
+Try it online at http://bogbook.com/ !
+
+### What?
+
+bogbook is a distributed social networking application using [TweetNaCl.js](https://tweetnacl.js.org/#/) to publish signed append-only logs to your browser's localStorage.
+
+The bogs are then gossiped between your bog client and bog 'pub' servers using websockets. You're responsible for syncing your messages between different bog 'pub' servers. Bog 'pubs' themselves don't talk to each other, instead they only talk to clients.
+
+When you click on a public key, your client will connect to your current pub to see if there are any new messages from the public key that you've clicked on.
+
+### But what about ssb?!
+
+This is _not_ [secure-scuttlebutt](http://scuttlebot.io/). But it is influenced by my 3+ years working on the project, and there are many similarities between bogbook and secure-scuttlebutt.
+
+The biggest difference is that all of the bogging happens in the client, making it a browser-first bogging network. Last I checked, ssb isn't leaving the server.
+
+Right now we have no private bogging, and no blob distribution (besides profile photos, which are saved to your log in base64).
+
+### how to
+
+bogbook servers
+
+```
+git clone git@github.com/bogbook/bogbook.git
+cd bogbook
+npm install
+npm start
+```
+
+Bogbook should launch in your browser. If it doesn't, navigate to http://localhost:8080/
+
+
+### crypto
+
+All of the bogbook cryptography is produced using [TweetNaCl.js](https://tweetnacl.js.org/#/) which is a port of [TweetNaCl](https://tweetnacl.cr.yp.to/), a cryptography library written in 100 Tweets.
+
+bogbook generates an ed25519 public/private keypair on load using `nacl.sign.keyPair()`, which is then stored in localStorage at `localStorage['id']` as a JSON object with the public/private keypairs base64-encoded.
+
+When you post a new message, bogbook will
+
++ iterate up the message sequence number
++ hash the contents of the previous message using sha512
++ sign the contents of the current message with your ed22519 private key
++ hash the new message (including the signature) using sha512
+
+before appending the feed to the log stored in your browser.
+
+Please note: All logs are append-only, public, and plain text at the current time. While you _can_ moderate your local database and pub servers by deleting logs associated with public keys, it can be difficult to unsay something, so don't drink and bog, people.
+
+Some browsers clear localStorage upon exit, others will clear it if you wipe your browser cache. Remember to save your public/private keypair somewhere, because no one can regenerate it for you.
+
+### contributing
+
+Please report all bugs at http://bogbook.com/
+
+---
+MIT
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..d3b8f04
--- /dev/null
+++ b/server.js
@@ -0,0 +1,58 @@
+// static server (8089)
+
+var http = require('http')
+var serve = require('ecstatic')
+
+http.createServer(
+ serve({ root: __dirname})
+).listen(8089)
+
+// websocket server (8080)
+
+
+var WebSocket = require('ws')
+var fs = require('fs')
+
+var wss = new WebSocket.Server({ port: 8080 })
+
+wss.on('connection', function (ws) {
+ ws.on('message', function (message) {
+ var receivedLog = JSON.parse(message)
+ if (receivedLog.publicKey) {
+ var publicKey = receivedLog.publicKey
+
+ var clientLog = receivedLog.log
+ // check to see if log is on server
+ if (fs.existsSync(__dirname + '/bogs/' + publicKey)) {
+ var serverLog = JSON.parse(fs.readFileSync(__dirname + '/bogs/' + receivedLog.publicKey))
+ // if the server log has more entries than the log in the client, send the server log to the client
+ if (serverLog.length > clientLog.length) {
+ sendingLog = {
+ publicKey: publicKey,
+ log: serverLog
+ }
+ ws.send(JSON.stringify(sendingLog))
+ console.log('SENT LOG TO CLIENT')
+ }
+ // if server log has less entries than the log sent by the client, write it to the server
+ if (serverLog.length < clientLog.length) {
+ fs.writeFile(__dirname + '/bogs/' + publicKey, JSON.stringify(clientLog), function (err) {
+ if (err) throw err
+ console.log('SAVED LOG TO SERVER')
+ })
+ }
+ // if logs are identical, do nothing
+ if (serverLog.length == clientLog.length) {
+ console.log('LOGS ARE THE SAME')
+ }
+ // if log doesn't already exist, write it
+ } else {
+ fs.writeFile(__dirname + '/bogs/' + publicKey, JSON.stringify(clientLog), function (err) {
+ if (err) throw err
+ console.log('SAVED LOG TO SERVER')
+ })
+ }
+ }
+ })
+})
+