├── .nrepl-port ├── resources └── public │ ├── contracts │ ├── build │ │ ├── strings.abi │ │ ├── strings.bin │ │ ├── SimpleTwitter.abi │ │ ├── SimpleTwitter.bin │ │ └── SimpleTwitter.json │ └── src │ │ ├── SimpleTwitter.sol │ │ └── strings.sol │ ├── index.html │ ├── less │ └── styles.main.less │ └── css │ ├── styles.css │ └── styles.main.css.map ├── Procfile ├── .gitignore ├── compile-solidity.sh ├── env └── dev │ └── user.clj ├── src ├── cljs │ └── clojurescript_ethereum_example │ │ ├── subs.cljs │ │ ├── core.cljs │ │ ├── db.cljs │ │ ├── address_select_field.cljs │ │ ├── utils.cljs │ │ ├── views.cljs │ │ └── handlers.cljs └── clj │ └── clojurescript_ethereum_example │ └── core.clj ├── README.md ├── project.clj └── clojurescript-ethereum-example.iml /.nrepl-port: -------------------------------------------------------------------------------- 1 | 62049 -------------------------------------------------------------------------------- /resources/public/contracts/build/strings.abi: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: java $JVM_OPTS -cp target/clojurescript-ethereum-example.jar clojure.main -m clojurescript-ethereum-example.core -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /*.log 2 | /target 3 | /*-init.clj 4 | /resources/public/js/compiled 5 | out 6 | /figwheel_server.log 7 | /.idea/ 8 | /.nrepl-port 9 | /clojurescript-ethereum-example.iml 10 | -------------------------------------------------------------------------------- /resources/public/contracts/build/strings.bin: -------------------------------------------------------------------------------- 1 | 60606040523415600b57fe5b5b60338060196000396000f30060606040525bfe00a165627a7a72305820062c7f243b9e78c027276fbfed3e8d740ecfff565b17101d5dcf06a4caf4f6380029 -------------------------------------------------------------------------------- /compile-solidity.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd resources/public/contracts/src 3 | solc --overwrite --optimize --bin --abi --combined-json bin,abi SimpleTwitter.sol -o ../build/ > ../build/SimpleTwitter.json 4 | -------------------------------------------------------------------------------- /env/dev/user.clj: -------------------------------------------------------------------------------- 1 | (ns user 2 | (:require [figwheel-sidecar.repl-api] 3 | [clojurescript-ethereum-example.core] 4 | [ring.middleware.reload :refer [wrap-reload]])) 5 | 6 | (set! *warn-on-reflection* true) 7 | (set! *unchecked-math* :warn-on-boxed) 8 | 9 | (def http-handler 10 | (wrap-reload #'clojurescript-ethereum-example.core/http-handler)) -------------------------------------------------------------------------------- /resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/cljs/clojurescript_ethereum_example/subs.cljs: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.subs 2 | (:require [re-frame.core :refer [reg-sub]])) 3 | 4 | (reg-sub 5 | :db/my-addresses 6 | (fn [db] 7 | (:my-addresses db))) 8 | 9 | (reg-sub 10 | :db/tweets 11 | (fn [db] 12 | (sort-by :date #(compare %2 %1) (:tweets db)))) 13 | 14 | (reg-sub 15 | :db/new-tweet 16 | (fn [db] 17 | (:new-tweet db))) 18 | 19 | (reg-sub 20 | :db/settings 21 | (fn [db] 22 | (:settings db))) 23 | 24 | (reg-sub 25 | :new-tweet/selected-address-balance 26 | (fn [db] 27 | (get-in db [:accounts (:address (:new-tweet db)) :balance]))) 28 | -------------------------------------------------------------------------------- /src/cljs/clojurescript_ethereum_example/core.cljs: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.core 2 | (:require 3 | [cljs-time.extend] 4 | [cljsjs.material-ui] 5 | [cljsjs.react-flexbox-grid] 6 | [cljsjs.web3] 7 | [clojurescript-ethereum-example.handlers] 8 | [clojurescript-ethereum-example.subs] 9 | [clojurescript-ethereum-example.views :as views] 10 | [print.foo.preloads.devtools] 11 | [re-frame.core :as re-frame] 12 | [reagent.core :as reagent] 13 | )) 14 | 15 | 16 | (enable-console-print!) 17 | 18 | (defn mount-root [] 19 | (reagent/render [views/main-panel] 20 | (.getElementById js/document "app"))) 21 | 22 | (defn ^:export init [] 23 | (re-frame/dispatch-sync [:initialize]) 24 | (mount-root)) 25 | -------------------------------------------------------------------------------- /src/cljs/clojurescript_ethereum_example/db.cljs: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.db 2 | (:require [cljs-web3.core :as web3])) 3 | 4 | (def default-db 5 | {:tweets [] 6 | :settings {} 7 | :my-addresses [] 8 | :accounts {} 9 | :new-tweet {:text "" 10 | :name "" 11 | :address nil 12 | :sending? false} 13 | :web3 (or (aget js/window "web3") 14 | (if goog.DEBUG 15 | (web3/create-web3 "http://localhost:8545/") 16 | (web3/create-web3 "https://morden.infura.io/metamask"))) 17 | :provides-web3? (or (aget js/window "web3") goog.DEBUG) 18 | :contract {:name "SimpleTwitter" 19 | :abi nil 20 | :bin nil 21 | :instance nil 22 | :address "0xe70a510651c3394f546f187c441303fd6520a1cd"}}) 23 | -------------------------------------------------------------------------------- /resources/public/less/styles.main.less: -------------------------------------------------------------------------------- 1 | @import (inline) "cljsjs/react-flexbox-grid/production/react-flexbox-grid.min.inc.css"; 2 | 3 | 4 | a { 5 | color: #ff4081; 6 | text-decoration: none; 7 | } 8 | 9 | a.no-decor { 10 | color: inherit !important; 11 | } 12 | 13 | a:hover { 14 | text-decoration: underline; 15 | } 16 | 17 | a.no-decor:hover { 18 | text-decoration: none; 19 | } 20 | 21 | html { 22 | font-family: 'Roboto', sans-serif; 23 | -webkit-font-smoothing: antialiased; 24 | } 25 | 26 | body { 27 | background-color: #efefef; 28 | } 29 | 30 | body, h1, h2, h3, h4, h5, h6 { 31 | margin: 0; 32 | color: rgba(0,0,0,.87); 33 | } 34 | 35 | h1, h2, h3, h4, h5, h6 { 36 | font-weight: 300; 37 | } 38 | 39 | body { 40 | font-size: 15px; 41 | line-height: 24px; 42 | } 43 | 44 | strong, b { 45 | font-weight: 500; 46 | } 47 | -------------------------------------------------------------------------------- /src/cljs/clojurescript_ethereum_example/address_select_field.cljs: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.address-select-field 2 | (:require 3 | [cljs-react-material-ui.reagent :as ui] 4 | [clojurescript-ethereum-example.utils :as u] 5 | [re-frame.core :refer [dispatch]] 6 | [reagent.core :as r])) 7 | 8 | (defn address-select-field [addresses selected-address dispatch-vec & [props]] 9 | (let [no-addresses? (empty? addresses)] 10 | [ui/select-field 11 | (r/merge-props 12 | {:value selected-address 13 | :on-change #(dispatch (conj dispatch-vec %3)) 14 | :disabled no-addresses? 15 | :style {:text-align :left} 16 | :floating-label-text (if no-addresses? "No Accounts Connected" "Choose your account")} 17 | props) 18 | (for [address addresses] 19 | [ui/menu-item 20 | {:value address 21 | :key address 22 | :primary-text (u/truncate address 25)}])])) 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Clojure Ethereum Example 2 | 3 | This is source code for tutorials: 4 | * [How to create decentralised apps with Clojurescript re-frame and Ethereum](https://medium.com/@matus.lestan/how-to-create-decentralised-apps-with-clojurescript-re-frame-and-ethereum-81de24d72ff5#.nvfyq27lb) 5 | * [How to deploy Clojurescript app into distributed storage IPFS](https://medium.com/@matus.lestan/how-to-deploy-clojurescript-app-into-distributed-storage-ipfs-e9d02cdfbc20#.ax3ra84bz) 6 | 7 | Deployed at: 8 | * https://clojurescript-ethereum-example.herokuapp.com/ 9 | * https://ipfs.io/ipns/QmXj5vKEKSU4kkjGnWq9ZJeG4xrkacDugme4iXz6qtvPgN/ 10 | 11 | ## Start App 12 | Start Solidity auto compiling 13 | ``` 14 | lein auto compile-solidity 15 | ``` 16 | Start less compiling 17 | ``` 18 | lein less4j auto 19 | ``` 20 | Start App 21 | ``` 22 | lein repl 23 | ``` 24 | ```clojure 25 | (clojurescript-ethereum-example.core/-main) 26 | (figwheel-sidecar.repl-api/start-figwheel! (figwheel-sidecar.config/fetch-config)) 27 | (figwheel-sidecar.repl-api/cljs-repl) 28 | ``` 29 | Open at http://localhost:6655/ 30 | 31 | -------------------------------------------------------------------------------- /src/cljs/clojurescript_ethereum_example/utils.cljs: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.utils 2 | (:require [cljs-time.coerce :refer [to-date-time to-long to-local-date-time]] 3 | [cljs-time.core :refer [date-time to-default-time-zone]] 4 | [cljs-time.format :as time-format] 5 | [cljs-web3.core :as web3])) 6 | 7 | (defn truncate 8 | "Truncate a string with suffix (ellipsis by default) if it is 9 | longer than specified length." 10 | ([string length] 11 | (truncate string length "...")) 12 | ([string length suffix] 13 | (let [string-len (count string) 14 | suffix-len (count suffix)] 15 | (if (<= string-len length) 16 | string 17 | (str (subs string 0 (- length suffix-len)) suffix))))) 18 | 19 | (defn evt-val [e] 20 | (aget e "target" "value")) 21 | 22 | (defn big-number->date-time [big-num] 23 | (to-date-time (* (.toNumber big-num) 1000))) 24 | 25 | (defn eth [big-num] 26 | (str (web3/from-wei big-num :ether) " ETH")) 27 | 28 | (defn format-date [date] 29 | (time-format/unparse-local (time-format/formatters :rfc822) (to-default-time-zone (to-date-time date)))) 30 | -------------------------------------------------------------------------------- /src/clj/clojurescript_ethereum_example/core.clj: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.core 2 | (:require [clojure.java.io :as io] 3 | [compojure.core :refer [ANY GET PUT POST DELETE defroutes]] 4 | [compojure.route :refer [resources]] 5 | [ring.middleware.defaults :refer [wrap-defaults site-defaults]] 6 | [ring.middleware.gzip :refer [wrap-gzip]] 7 | [ring.middleware.logger :refer [wrap-with-logger]] 8 | [environ.core :refer [env]] 9 | [org.httpkit.server :refer [run-server]]) 10 | (:gen-class)) 11 | 12 | (def ^:dynamic *server*) 13 | 14 | (defroutes routes 15 | (GET "/js/*" _ 16 | {:status 404}) 17 | (GET "/*" _ 18 | {:status 200 19 | :headers {"Content-Type" "text/html; charset=utf-8"} 20 | :body (io/input-stream (io/resource "public/index.html"))})) 21 | 22 | (def http-handler 23 | (-> routes 24 | (wrap-defaults site-defaults) 25 | wrap-with-logger 26 | wrap-gzip)) 27 | 28 | (defn -main [& [port]] 29 | (let [port (Integer. (or port (env :port) 6655))] 30 | (alter-var-root (var *server*) 31 | (constantly (run-server http-handler {:port port :join? false}))))) 32 | 33 | (defn stop-server [] 34 | (*server*) 35 | (alter-var-root (var *server*) (constantly nil))) 36 | 37 | (defn restart-server [] 38 | (stop-server) 39 | (-main)) 40 | 41 | (comment 42 | (restart-server) 43 | (-main) 44 | (stop-server)) -------------------------------------------------------------------------------- /resources/public/contracts/src/SimpleTwitter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.1; 2 | 3 | import "strings.sol"; 4 | 5 | contract SimpleTwitter { 6 | using strings for *; 7 | 8 | address public developer; 9 | uint16 public maxTweetLength; 10 | uint16 public maxNameLength; 11 | 12 | struct Tweet { 13 | address authorAddress; 14 | string name; 15 | string text; 16 | uint date; 17 | } 18 | 19 | Tweet[] public tweets; 20 | 21 | event onTweetAdded(address authorAddress, string name, string text, uint date, uint tweetKey); 22 | 23 | modifier onlyDeveloper() { 24 | if (msg.sender != developer) throw; 25 | _; 26 | } 27 | 28 | function SimpleTwitter() { 29 | maxTweetLength = 140; 30 | maxNameLength = 20; 31 | developer = msg.sender; 32 | } 33 | 34 | function addTweet(string name, string text) { 35 | if (name.toSlice().len() > maxNameLength) throw; 36 | if (text.toSlice().len() > maxTweetLength) throw; 37 | 38 | tweets.push(Tweet(msg.sender, name, text, now)); 39 | onTweetAdded(msg.sender, name, text, now, tweets.length - 1); 40 | } 41 | 42 | function getSettings() constant returns(uint16, uint16) { 43 | return (maxNameLength, maxTweetLength); 44 | } 45 | 46 | function setSettings(uint16 _maxNameLength, uint16 _maxTweetLength) onlyDeveloper { 47 | maxNameLength = _maxNameLength; 48 | maxTweetLength = _maxTweetLength; 49 | } 50 | } -------------------------------------------------------------------------------- /resources/public/contracts/build/SimpleTwitter.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[],"name":"maxTweetLength","outputs":[{"name":"","type":"uint16"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_maxNameLength","type":"uint16"},{"name":"_maxTweetLength","type":"uint16"}],"name":"setSettings","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"maxNameLength","outputs":[{"name":"","type":"uint16"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"text","type":"string"}],"name":"addTweet","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getSettings","outputs":[{"name":"","type":"uint16"},{"name":"","type":"uint16"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"developer","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"tweets","outputs":[{"name":"authorAddress","type":"address"},{"name":"name","type":"string"},{"name":"text","type":"string"},{"name":"date","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"authorAddress","type":"address"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"text","type":"string"},{"indexed":false,"name":"date","type":"uint256"},{"indexed":false,"name":"tweetKey","type":"uint256"}],"name":"onTweetAdded","type":"event"}] -------------------------------------------------------------------------------- /src/cljs/clojurescript_ethereum_example/views.cljs: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.views 2 | (:require 3 | [re-frame.core :refer [dispatch subscribe]] 4 | [reagent.core :as r] 5 | [clojurescript-ethereum-example.address-select-field :refer [address-select-field]] 6 | [cljs-react-material-ui.reagent :as ui] 7 | [cljs-react-material-ui.core :refer [get-mui-theme color]] 8 | [clojurescript-ethereum-example.utils :as u])) 9 | 10 | (def col (r/adapt-react-class js/ReactFlexboxGrid.Col)) 11 | (def row (r/adapt-react-class js/ReactFlexboxGrid.Row)) 12 | 13 | (defn- new-tweet-component [] 14 | (let [settings (subscribe [:db/settings]) 15 | new-tweet (subscribe [:db/new-tweet]) 16 | my-addresses (subscribe [:db/my-addresses]) 17 | balance (subscribe [:new-tweet/selected-address-balance])] 18 | (fn [] 19 | [row 20 | [col {:xs 12 :sm 12 :md 10 :lg 6 :md-offset 1 :lg-offset 3} 21 | [ui/paper {:style {:padding "0 20px 20px"}} 22 | [ui/text-field {:default-value (:name @new-tweet) 23 | :on-change #(dispatch [:new-tweet/update :name (u/evt-val %)]) 24 | :name "name" 25 | :max-length (:max-name-length @settings) 26 | :floating-label-text "Your Name" 27 | :style {:width "100%"}}] 28 | [:br] 29 | [ui/text-field {:default-value (:text @new-tweet) 30 | :on-change #(dispatch [:new-tweet/update :text (u/evt-val %)]) 31 | :name "tweet" 32 | :max-length (:max-tweet-length @settings) 33 | :floating-label-text "What's happening?" 34 | :style {:width "100%"}}] 35 | [:br] 36 | [address-select-field 37 | @my-addresses 38 | (:address @new-tweet) 39 | [:new-tweet/update :address]] 40 | [:br] 41 | [:h3 "Balance: " (u/eth @balance)] 42 | [:br] 43 | [ui/raised-button 44 | {:secondary true 45 | :disabled (or (empty? (:text @new-tweet)) 46 | (empty? (:name @new-tweet)) 47 | (empty? (:address @new-tweet)) 48 | (:sending? @new-tweet)) 49 | :label "Tweet" 50 | :style {:margin-top 15} 51 | :on-touch-tap #(dispatch [:new-tweet/send])}]]]]))) 52 | 53 | (defn- tweets-component [] 54 | (let [tweets (subscribe [:db/tweets])] 55 | (fn [] 56 | [row 57 | [col {:xs 12 :sm 12 :md 10 :lg 6 :md-offset 1 :lg-offset 3} 58 | [ui/paper {:style {:padding 20 :margin-top 20}} 59 | [:h1 "Tweets"] 60 | (for [{:keys [tweet-key name text date author-address]} @tweets] 61 | [:div {:style {:margin-top 20} 62 | :key tweet-key} 63 | [:h3 name] 64 | [:h5 (u/format-date date)] 65 | [:div {:style {:margin-top 5}} 66 | text] 67 | [:h3 {:style {:margin "5px 0 10px"}} 68 | author-address] 69 | [ui/divider]])]]]))) 70 | 71 | (defn main-panel [] 72 | (let [] 73 | (fn [] 74 | [ui/mui-theme-provider 75 | {:mui-theme (get-mui-theme {:palette {:primary1-color (color :light-blue500) 76 | :accent1-color (color :amber700)}})} 77 | [:div 78 | [ui/app-bar {:title "Simple Decentralized Twitter"}] 79 | [new-tweet-component] 80 | [tweets-component]]]))) 81 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject clojurescript-ethereum-example "0.1.0-SNAPSHOT" 2 | :dependencies [[bk/ring-gzip "0.1.1"] 3 | [cljs-ajax "0.5.8"] 4 | [cljs-react-material-ui "0.2.22"] 5 | [cljs-web3 "0.16.0-0"] 6 | [cljsjs/bignumber "2.1.4-1"] 7 | [cljsjs/react-flexbox-grid "0.10.2-1" :exclusions [cljsjs/react]] 8 | [com.andrewmcveigh/cljs-time "0.4.0"] 9 | [compojure "1.6.0-beta1"] 10 | [day8.re-frame/http-fx "0.0.4"] 11 | [environ "1.0.3"] 12 | [http-kit "2.2.0"] 13 | [madvas.re-frame/web3-fx "0.1.0"] 14 | [medley "0.8.3"] 15 | [org.clojure/clojure "1.8.0"] 16 | [org.clojure/clojurescript "1.9.229"] 17 | [print-foo-cljs "2.0.3"] 18 | [re-frame "0.8.0"] 19 | [reagent "0.6.0" :exclusions [cljsjs/react]] 20 | [ring.middleware.logger "0.5.0"] 21 | [ring/ring-core "1.6.0-beta5"] 22 | [ring/ring-defaults "0.3.0-beta1"] 23 | [ring/ring-devel "1.6.0-beta5"]] 24 | 25 | :plugins [[lein-auto "0.1.2"] 26 | [lein-cljsbuild "1.1.4"] 27 | [lein-shell "0.5.0"] 28 | [deraen/lein-less4j "0.5.0"]] 29 | 30 | :min-lein-version "2.5.3" 31 | :main clojurescript-ethereum-example.core 32 | 33 | :source-paths ["src/clj"] 34 | 35 | :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"] 36 | 37 | :figwheel {:css-dirs ["resources/public/css"] 38 | :server-port 6777 39 | :ring-handler user/http-handler} 40 | 41 | :auto {"compile-solidity" {:file-pattern #"\.(sol)$" 42 | :paths ["resources/public/contracts/src"]}} 43 | 44 | :aliases {"compile-solidity" ["shell" "./compile-solidity.sh"]} 45 | 46 | :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]} 47 | 48 | :less {:source-paths ["resources/public/less"] 49 | :target-path "resources/public/css" 50 | :target-dir "resources/public/css" 51 | :source-map true 52 | :compression true} 53 | 54 | :uberjar-name "clojurescript-ethereum-example.jar" 55 | 56 | :profiles 57 | {:dev 58 | {:dependencies [[binaryage/devtools "0.8.2"] 59 | [com.cemerick/piggieback "0.2.1"] 60 | [figwheel-sidecar "0.5.8"] 61 | [org.clojure/tools.nrepl "0.2.11"]] 62 | :plugins [[lein-figwheel "0.5.8"]] 63 | :source-paths ["env/dev"] 64 | :cljsbuild {:builds [{:id "dev" 65 | :source-paths ["src/cljs"] 66 | :figwheel {:on-jsload "clojurescript-ethereum-example.core/mount-root"} 67 | :compiler {:main clojurescript-ethereum-example.core 68 | :output-to "resources/public/js/compiled/app.js" 69 | :output-dir "resources/public/js/compiled/out" 70 | :asset-path "./js/compiled/out" 71 | :source-map-timestamp true 72 | :optimizations :none 73 | :closure-defines {goog.DEBUG true} 74 | :preloads [print.foo.preloads.devtools]}}]}} 75 | 76 | :uberjar {:hooks [leiningen.cljsbuild] 77 | :omit-source true 78 | :aot :all 79 | :main emojillionaire.core 80 | :cljsbuild {:builds {:app {:id "uberjar" 81 | :source-paths ["src/cljs"] 82 | :compiler {:main clojurescript-ethereum-example.core 83 | :output-to "resources/public/js/compiled/app.js" 84 | :optimizations :advanced 85 | :closure-defines {goog.DEBUG false} 86 | :pretty-print true 87 | :pseudo-names true}}}}}}) 88 | -------------------------------------------------------------------------------- /resources/public/contracts/build/SimpleTwitter.bin: -------------------------------------------------------------------------------- 1 | 6060604052341561000c57fe5b5b6000805460a060020a61ffff021916748c00000000000000000000000000000000000000001760b060020a61ffff02191676140000000000000000000000000000000000000000000017600160a060020a03191633600160a060020a03161790555b5b6109018061007f6000396000f300606060405236156100805763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166313ce93588114610082578063398b91af146100a95780633b992f2b146100c85780637e75b408146100ef57806385b4bb5314610184578063ca4b208b146101b5578063e8d857b0146101e1575bfe5b341561008a57fe5b61009261030f565b6040805161ffff9092168252519081900360200190f35b34156100b157fe5b6100c661ffff60043581169060243516610320565b005b34156100d057fe5b610092610398565b6040805161ffff9092168252519081900360200190f35b34156100f757fe5b6100c6600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506103a995505050505050565b005b341561018c57fe5b6101946105f8565b6040805161ffff938416815291909216602082015281519081900390910190f35b34156101bd57fe5b6101c5610615565b60408051600160a060020a039092168252519081900360200190f35b34156101e957fe5b6101f4600435610624565b60408051600160a060020a038616815260608101839052608060208201818152865460026000196101006001841615020190911604918301829052919283019060a0840190879080156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b50508381038252855460026000196101006001841615020190911604808252602090910190869080156102fc5780601f106102d1576101008083540402835291602001916102fc565b820191906000526020600020905b8154815290600101906020018083116102df57829003601f168201915b5050965050505050505060405180910390f35b60005460a060020a900461ffff1681565b60005433600160a060020a0390811691161461033c5760006000fd5b6000805461ffff83811660a060020a0275ffff00000000000000000000000000000000000000001991861660b060020a0277ffff000000000000000000000000000000000000000000001990931692909217161790555b5b5050565b60005460b060020a900461ffff1681565b60005460b060020a900461ffff166103c86103c384610664565b61068d565b11156103d45760006000fd5b60005460a060020a900461ffff166103f36103c383610664565b61068d565b11156103ff5760006000fd5b600180548082016104108382610747565b916000526020600020906004020160005b5060408051608081018252600160a060020a0333168082526020808301889052928201869052426060830152835473ffffffffffffffffffffffffffffffffffffffff1916178355855190929161047f916001840191880190610779565b506040820151805161049b916002840191602090910190610779565b50606082015181600301555050507f9a09b2b614ff0b166c21753b02abd530af36fc391ffaa6c43f7f7a3884f7b147338383426001600180549050036040518086600160a060020a0316600160a060020a03168152602001806020018060200185815260200184815260200183810383528781815181526020019150805190602001908083836000831461054a575b80518252602083111561054a57601f19909201916020918201910161052a565b505050905090810190601f1680156105765780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838382156105b5575b8051825260208311156105b557601f199092019160209182019101610595565b505050905090810190601f1680156105e15780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15b5050565b60005461ffff60b060020a820481169160a060020a9004165b9091565b600054600160a060020a031681565b600180548290811061063257fe5b906000526020600020906004020160005b5080546003820154600160a060020a03909116925060018201916002019084565b61066c6107f8565b50604080518082019091528151815260208281019082018190525b50919050565b60208101518151600091601e19808201929091010182805b8284101561073a5750825160ff1660808110156106c75760018401935061072a565b60e08160ff1610156106de5760028401935061072a565b60f08160ff1610156106f55760038401935061072a565b60f88160ff16101561070c5760048401935061072a565b60fc8160ff1610156107235760058401935061072a565b6006840193505b5b5b5b5b5b6001909101906106a5565b8194505b50505050919050565b81548183558181151161077357600402816004028360005260206000209182019101610773919061080f565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107ba57805160ff19168380011785556107e7565b828001600101855582156107e7579182015b828111156107e75782518255916020019190600101906107cc565b5b506107f492915061086c565b5090565b604080518082019091526000808252602082015290565b61086991905b808211156107f457805473ffffffffffffffffffffffffffffffffffffffff191681556000610847600183018261088d565b61085560028301600061088d565b5060006003820155600401610815565b5090565b90565b61086991905b808211156107f45760008155600101610872565b5090565b90565b50805460018160011615610100020316600290046000825580601f106108b357506108d1565b601f0160209004906000526020600020908101906108d1919061086c565b5b505600a165627a7a723058203360392f78910e972f522f7f2c06fcc2f4095a4607e84e4d0388654696cf80280029 -------------------------------------------------------------------------------- /resources/public/contracts/build/SimpleTwitter.json: -------------------------------------------------------------------------------- 1 | {"contracts":{"SimpleTwitter.sol:SimpleTwitter":{"abi":"[{\"constant\":true,\"inputs\":[],\"name\":\"maxTweetLength\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_maxNameLength\",\"type\":\"uint16\"},{\"name\":\"_maxTweetLength\",\"type\":\"uint16\"}],\"name\":\"setSettings\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"maxNameLength\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"text\",\"type\":\"string\"}],\"name\":\"addTweet\",\"outputs\":[],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getSettings\",\"outputs\":[{\"name\":\"\",\"type\":\"uint16\"},{\"name\":\"\",\"type\":\"uint16\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"developer\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"tweets\",\"outputs\":[{\"name\":\"authorAddress\",\"type\":\"address\"},{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"text\",\"type\":\"string\"},{\"name\":\"date\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"authorAddress\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"name\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"text\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"date\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tweetKey\",\"type\":\"uint256\"}],\"name\":\"onTweetAdded\",\"type\":\"event\"}]","bin":"6060604052341561000c57fe5b5b6000805460a060020a61ffff021916748c00000000000000000000000000000000000000001760b060020a61ffff02191676140000000000000000000000000000000000000000000017600160a060020a03191633600160a060020a03161790555b5b6109018061007f6000396000f300606060405236156100805763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166313ce93588114610082578063398b91af146100a95780633b992f2b146100c85780637e75b408146100ef57806385b4bb5314610184578063ca4b208b146101b5578063e8d857b0146101e1575bfe5b341561008a57fe5b61009261030f565b6040805161ffff9092168252519081900360200190f35b34156100b157fe5b6100c661ffff60043581169060243516610320565b005b34156100d057fe5b610092610398565b6040805161ffff9092168252519081900360200190f35b34156100f757fe5b6100c6600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f89358b018035918201839004830284018301909452808352979998810197919650918201945092508291508401838280828437509496506103a995505050505050565b005b341561018c57fe5b6101946105f8565b6040805161ffff938416815291909216602082015281519081900390910190f35b34156101bd57fe5b6101c5610615565b60408051600160a060020a039092168252519081900360200190f35b34156101e957fe5b6101f4600435610624565b60408051600160a060020a038616815260608101839052608060208201818152865460026000196101006001841615020190911604918301829052919283019060a0840190879080156102885780601f1061025d57610100808354040283529160200191610288565b820191906000526020600020905b81548152906001019060200180831161026b57829003601f168201915b50508381038252855460026000196101006001841615020190911604808252602090910190869080156102fc5780601f106102d1576101008083540402835291602001916102fc565b820191906000526020600020905b8154815290600101906020018083116102df57829003601f168201915b5050965050505050505060405180910390f35b60005460a060020a900461ffff1681565b60005433600160a060020a0390811691161461033c5760006000fd5b6000805461ffff83811660a060020a0275ffff00000000000000000000000000000000000000001991861660b060020a0277ffff000000000000000000000000000000000000000000001990931692909217161790555b5b5050565b60005460b060020a900461ffff1681565b60005460b060020a900461ffff166103c86103c384610664565b61068d565b11156103d45760006000fd5b60005460a060020a900461ffff166103f36103c383610664565b61068d565b11156103ff5760006000fd5b600180548082016104108382610747565b916000526020600020906004020160005b5060408051608081018252600160a060020a0333168082526020808301889052928201869052426060830152835473ffffffffffffffffffffffffffffffffffffffff1916178355855190929161047f916001840191880190610779565b506040820151805161049b916002840191602090910190610779565b50606082015181600301555050507f9a09b2b614ff0b166c21753b02abd530af36fc391ffaa6c43f7f7a3884f7b147338383426001600180549050036040518086600160a060020a0316600160a060020a03168152602001806020018060200185815260200184815260200183810383528781815181526020019150805190602001908083836000831461054a575b80518252602083111561054a57601f19909201916020918201910161052a565b505050905090810190601f1680156105765780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838382156105b5575b8051825260208311156105b557601f199092019160209182019101610595565b505050905090810190601f1680156105e15780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390a15b5050565b60005461ffff60b060020a820481169160a060020a9004165b9091565b600054600160a060020a031681565b600180548290811061063257fe5b906000526020600020906004020160005b5080546003820154600160a060020a03909116925060018201916002019084565b61066c6107f8565b50604080518082019091528151815260208281019082018190525b50919050565b60208101518151600091601e19808201929091010182805b8284101561073a5750825160ff1660808110156106c75760018401935061072a565b60e08160ff1610156106de5760028401935061072a565b60f08160ff1610156106f55760038401935061072a565b60f88160ff16101561070c5760048401935061072a565b60fc8160ff1610156107235760058401935061072a565b6006840193505b5b5b5b5b5b6001909101906106a5565b8194505b50505050919050565b81548183558181151161077357600402816004028360005260206000209182019101610773919061080f565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107ba57805160ff19168380011785556107e7565b828001600101855582156107e7579182015b828111156107e75782518255916020019190600101906107cc565b5b506107f492915061086c565b5090565b604080518082019091526000808252602082015290565b61086991905b808211156107f457805473ffffffffffffffffffffffffffffffffffffffff191681556000610847600183018261088d565b61085560028301600061088d565b5060006003820155600401610815565b5090565b90565b61086991905b808211156107f45760008155600101610872565b5090565b90565b50805460018160011615610100020316600290046000825580601f106108b357506108d1565b601f0160209004906000526020600020908101906108d1919061086c565b5b505600a165627a7a723058203360392f78910e972f522f7f2c06fcc2f4095a4607e84e4d0388654696cf80280029"},"strings.sol:strings":{"abi":"[]","bin":"60606040523415600b57fe5b5b60338060196000396000f30060606040525bfe00a165627a7a72305820062c7f243b9e78c027276fbfed3e8d740ecfff565b17101d5dcf06a4caf4f6380029"}},"version":"0.4.11+commit.68ef5810.Linux.g++"} 2 | -------------------------------------------------------------------------------- /src/cljs/clojurescript_ethereum_example/handlers.cljs: -------------------------------------------------------------------------------- 1 | (ns clojurescript-ethereum-example.handlers 2 | (:require 3 | [ajax.core :as ajax] 4 | [cljs-web3.core :as web3] 5 | [cljs-web3.eth :as web3-eth] 6 | [cljs-web3.personal :as web3-personal] 7 | [cljsjs.web3] 8 | [clojurescript-ethereum-example.db :as db] 9 | [day8.re-frame.http-fx] 10 | [goog.string :as gstring] 11 | [goog.string.format] 12 | [madvas.re-frame.web3-fx] 13 | [re-frame.core :refer [reg-event-db reg-event-fx path trim-v after debug reg-fx console dispatch]] 14 | [clojurescript-ethereum-example.utils :as u])) 15 | 16 | (def interceptors [#_(when ^boolean js/goog.DEBUG debug) 17 | trim-v]) 18 | 19 | (def tweet-gas-limit 1000000) 20 | 21 | (comment 22 | (dispatch [:contract/fetch-compiled-code [:contract/deploy-compiled-code]]) 23 | (dispatch [:blockchain/unlock-account "0x6fce64667819c82a8bcbb78e294d7b444d2e1a29" "m"]) 24 | (dispatch [:blockchain/unlock-account "0xc5aa141d3822c3368df69bfd93ef2b13d1c59aec" "m"]) 25 | (dispatch [:blockchain/unlock-account "0xe206f52728e2c1e23de7d42d233f39ac2e748977" "m"]) 26 | (dispatch [:blockchain/unlock-account "0x522f9c6b122f4ca8067eb5459c10d03a35798ed9" "m"]) 27 | (dispatch [:blockchain/unlock-account "0x43100e355296c4fe3d2c0a356aa4151f1257393b" "m"]) 28 | ) 29 | 30 | (reg-event-fx 31 | :initialize 32 | (fn [_ _] 33 | (merge 34 | {:db db/default-db 35 | :http-xhrio {:method :get 36 | :uri (gstring/format "./contracts/build/%s.abi" 37 | (get-in db/default-db [:contract :name])) 38 | :timeout 6000 39 | :response-format (ajax/json-response-format {:keywords? true}) 40 | :on-success [:contract/abi-loaded] 41 | :on-failure [:log-error]}} 42 | (when (:provides-web3? db/default-db) 43 | {:web3-fx.blockchain/fns 44 | {:web3 (:web3 db/default-db) 45 | :fns [[web3-eth/accounts :blockchain/my-addresses-loaded :log-error]]}})))) 46 | 47 | (reg-event-fx 48 | :blockchain/my-addresses-loaded 49 | interceptors 50 | (fn [{:keys [db]} [addresses]] 51 | {:db (-> db 52 | (assoc :my-addresses addresses) 53 | (assoc-in [:new-tweet :address] (first addresses))) 54 | :web3-fx.blockchain/balances 55 | {:web3 (:web3 db/default-db) 56 | :addresses addresses 57 | :watch? true 58 | :blockchain-filter-opts "latest" 59 | :dispatches [:blockchain/balance-loaded :log-error]}})) 60 | 61 | (reg-event-fx 62 | :contract/abi-loaded 63 | interceptors 64 | (fn [{:keys [db]} [abi]] 65 | (let [web3 (:web3 db) 66 | contract-instance (web3-eth/contract-at web3 abi (:address (:contract db)))] 67 | 68 | {:db (assoc-in db [:contract :instance] contract-instance) 69 | 70 | :web3-fx.contract/events 71 | {:instance contract-instance 72 | :db db 73 | :db-path [:contract :events] 74 | :events [[:on-tweet-added {} {:from-block 0} :contract/on-tweet-loaded :log-error]]} 75 | 76 | :web3-fx.contract/constant-fns 77 | {:instance contract-instance 78 | :fns [[:get-settings :contract/settings-loaded :log-error]]}}))) 79 | 80 | (reg-event-db 81 | :contract/on-tweet-loaded 82 | interceptors 83 | (fn [db [tweet]] 84 | (update db :tweets conj (merge (select-keys tweet [:author-address :text :name]) 85 | {:date (u/big-number->date-time (:date tweet)) 86 | :tweet-key (.toNumber (:tweet-key tweet))})))) 87 | 88 | (reg-event-db 89 | :contract/settings-loaded 90 | interceptors 91 | (fn [db [[max-name-length max-tweet-length]]] 92 | (assoc db :settings {:max-name-length (.toNumber max-name-length) 93 | :max-tweet-length (.toNumber max-tweet-length)}))) 94 | 95 | (reg-event-db 96 | :blockchain/balance-loaded 97 | interceptors 98 | (fn [db [balance address]] 99 | (assoc-in db [:accounts address :balance] balance))) 100 | 101 | (reg-event-db 102 | :new-tweet/update 103 | interceptors 104 | (fn [db [key value]] 105 | (assoc-in db [:new-tweet key] value))) 106 | 107 | (reg-event-fx 108 | :new-tweet/send 109 | interceptors 110 | (fn [{:keys [db]} []] 111 | (let [{:keys [name text address]} (:new-tweet db)] 112 | {:web3-fx.contract/state-fn 113 | {:instance (:instance (:contract db)) 114 | :web3 (:web3 db) 115 | :db-path [:contract :send-tweet] 116 | :fn [:add-tweet name text 117 | {:from address 118 | :gas tweet-gas-limit} 119 | :new-tweet/confirmed 120 | :log-error 121 | :new-tweet/transaction-receipt-loaded]}}))) 122 | 123 | (reg-event-db 124 | :new-tweet/confirmed 125 | interceptors 126 | (fn [db [transaction-hash]] 127 | (assoc-in db [:new-tweet :sending?] true))) 128 | 129 | (reg-event-db 130 | :new-tweet/transaction-receipt-loaded 131 | interceptors 132 | (fn [db [{:keys [gas-used] :as transaction-receipt}]] 133 | (console :log transaction-receipt) 134 | (when (= gas-used tweet-gas-limit) 135 | (console :error "All gas used")) 136 | (assoc-in db [:new-tweet :sending?] false))) 137 | 138 | (reg-event-fx 139 | :contract/fetch-compiled-code 140 | interceptors 141 | (fn [{:keys [db]} [on-success]] 142 | {:http-xhrio {:method :get 143 | :uri (gstring/format "/contracts/build/%s.json" 144 | (get-in db [:contract :name])) 145 | :timeout 6000 146 | :response-format (ajax/json-response-format {:keywords? true}) 147 | :on-success on-success 148 | :on-failure [:log-error]}})) 149 | 150 | (reg-event-fx 151 | :contract/deploy-compiled-code 152 | interceptors 153 | (fn [{:keys [db]} [contracts]] 154 | (let [{:keys [abi bin]} (get-in contracts [:contracts (keyword (:name (:contract db)))])] 155 | {:web3-fx.blockchain/fns 156 | {:web3 (:web3 db) 157 | :fns [[web3-eth/contract-new 158 | (js/JSON.parse abi) 159 | {:gas 4500000 160 | :data bin 161 | :from (first (:my-addresses db))} 162 | :contract/deployed 163 | :log-error]]}}))) 164 | 165 | (reg-event-fx 166 | :blockchain/unlock-account 167 | interceptors 168 | (fn [{:keys [db]} [address password]] 169 | {:web3-fx.blockchain/fns 170 | {:web3 (:web3 db) 171 | :fns [[web3-personal/unlock-account address password 999999 172 | :blockchain/account-unlocked 173 | :log-error]]}})) 174 | 175 | (reg-event-fx 176 | :blockchain/account-unlocked 177 | interceptors 178 | (fn [{:keys [db]}] 179 | (console :log "Account was unlocked.") 180 | {})) 181 | 182 | (reg-event-fx 183 | :contract/deployed 184 | interceptors 185 | (fn [_ [contract-instance]] 186 | (when-let [address (aget contract-instance "address")] 187 | (console :log "Contract deployed at" address)))) 188 | 189 | (reg-event-fx 190 | :log-error 191 | interceptors 192 | (fn [_ [err]] 193 | (console :error err) 194 | {})) 195 | -------------------------------------------------------------------------------- /resources/public/css/styles.css: -------------------------------------------------------------------------------- 1 | .flexboxgrid__container-fluid___2lUES,.flexboxgrid__container___R2zU9{margin-right:auto;margin-left:auto}.flexboxgrid__container-fluid___2lUES{padding-right:2rem;padding-left:2rem}.flexboxgrid__row___1y_mg{box-sizing:border-box;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.flexboxgrid__row___1y_mg.flexboxgrid__reverse___1X682{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flexboxgrid__col___3RqPP.flexboxgrid__reverse___1X682{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flexboxgrid__col-xs___1ROHR,.flexboxgrid__col-xs-1___VtNIK,.flexboxgrid__col-xs-2___36nDa,.flexboxgrid__col-xs-3___2f2Ql,.flexboxgrid__col-xs-4___TxBJg,.flexboxgrid__col-xs-5___1HkK5,.flexboxgrid__col-xs-6___1DhV6,.flexboxgrid__col-xs-7___3o2m-,.flexboxgrid__col-xs-8___3ARGc,.flexboxgrid__col-xs-9___15qfl,.flexboxgrid__col-xs-10___2AWNv,.flexboxgrid__col-xs-11___3H-6F,.flexboxgrid__col-xs-12___phbtE,.flexboxgrid__col-xs-offset-0___10C7E,.flexboxgrid__col-xs-offset-1___12o_R,.flexboxgrid__col-xs-offset-2___2Hh-B,.flexboxgrid__col-xs-offset-3___8NCys,.flexboxgrid__col-xs-offset-4___dA0P1,.flexboxgrid__col-xs-offset-5___2MbdF,.flexboxgrid__col-xs-offset-6___3N3bt,.flexboxgrid__col-xs-offset-7___1yQDG,.flexboxgrid__col-xs-offset-8___2aEcW,.flexboxgrid__col-xs-offset-9___2haBv,.flexboxgrid__col-xs-offset-10___1QsVg,.flexboxgrid__col-xs-offset-11___29xQn,.flexboxgrid__col-xs-offset-12___1XWFb{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-xs___1ROHR{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-xs-1___VtNIK{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-xs-2___36nDa{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-xs-3___2f2Ql{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-xs-4___TxBJg{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-xs-5___1HkK5{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-xs-6___1DhV6{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-xs-7___3o2m-{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-xs-8___3ARGc{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-xs-9___15qfl{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-xs-10___2AWNv{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-xs-11___3H-6F{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-xs-12___phbtE{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-xs-offset-0___10C7E{margin-left:0}.flexboxgrid__col-xs-offset-1___12o_R{margin-left:8.33333333%}.flexboxgrid__col-xs-offset-2___2Hh-B{margin-left:16.66666667%}.flexboxgrid__col-xs-offset-3___8NCys{margin-left:25%}.flexboxgrid__col-xs-offset-4___dA0P1{margin-left:33.33333333%}.flexboxgrid__col-xs-offset-5___2MbdF{margin-left:41.66666667%}.flexboxgrid__col-xs-offset-6___3N3bt{margin-left:50%}.flexboxgrid__col-xs-offset-7___1yQDG{margin-left:58.33333333%}.flexboxgrid__col-xs-offset-8___2aEcW{margin-left:66.66666667%}.flexboxgrid__col-xs-offset-9___2haBv{margin-left:75%}.flexboxgrid__col-xs-offset-10___1QsVg{margin-left:83.33333333%}.flexboxgrid__col-xs-offset-11___29xQn{margin-left:91.66666667%}.flexboxgrid__start-xs___h8qdA{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-xs___1JWon{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-xs___33Mku{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-xs___UhA-V{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-xs___1h5t3{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-xs___2tRUa{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-xs___1okkK{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-xs___WFP84{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-xs___XoosK{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-xs___HnlRw{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}@media only screen and (min-width:48em){.flexboxgrid__container___R2zU9{width:49rem}.flexboxgrid__col-sm___3tZ-z,.flexboxgrid__col-sm-1___2Gca6,.flexboxgrid__col-sm-2___YETza,.flexboxgrid__col-sm-3___2irZQ,.flexboxgrid__col-sm-4___3kj7S,.flexboxgrid__col-sm-5___gAxuQ,.flexboxgrid__col-sm-6___vUdKH,.flexboxgrid__col-sm-7___22IcQ,.flexboxgrid__col-sm-8___2_YhB,.flexboxgrid__col-sm-9___2ubpx,.flexboxgrid__col-sm-10___262G9,.flexboxgrid__col-sm-11___39s7J,.flexboxgrid__col-sm-12___1e5Uk,.flexboxgrid__col-sm-offset-0___llQ6-,.flexboxgrid__col-sm-offset-1___1PFWu,.flexboxgrid__col-sm-offset-2___1DgbO,.flexboxgrid__col-sm-offset-3___3W5Iv,.flexboxgrid__col-sm-offset-4___3YToG,.flexboxgrid__col-sm-offset-5___609Vo,.flexboxgrid__col-sm-offset-6___TCeVQ,.flexboxgrid__col-sm-offset-7___csvBu,.flexboxgrid__col-sm-offset-8___11PYH,.flexboxgrid__col-sm-offset-9___24Evy,.flexboxgrid__col-sm-offset-10___1-lcE,.flexboxgrid__col-sm-offset-11___2ynFq,.flexboxgrid__col-sm-offset-12___3MBMi{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-sm___3tZ-z{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-sm-1___2Gca6{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-sm-2___YETza{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-sm-3___2irZQ{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-sm-4___3kj7S{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-sm-5___gAxuQ{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-sm-6___vUdKH{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-sm-7___22IcQ{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-sm-8___2_YhB{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-sm-9___2ubpx{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-sm-10___262G9{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-sm-11___39s7J{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-sm-12___1e5Uk{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-sm-offset-0___llQ6-{margin-left:0}.flexboxgrid__col-sm-offset-1___1PFWu{margin-left:8.33333333%}.flexboxgrid__col-sm-offset-2___1DgbO{margin-left:16.66666667%}.flexboxgrid__col-sm-offset-3___3W5Iv{margin-left:25%}.flexboxgrid__col-sm-offset-4___3YToG{margin-left:33.33333333%}.flexboxgrid__col-sm-offset-5___609Vo{margin-left:41.66666667%}.flexboxgrid__col-sm-offset-6___TCeVQ{margin-left:50%}.flexboxgrid__col-sm-offset-7___csvBu{margin-left:58.33333333%}.flexboxgrid__col-sm-offset-8___11PYH{margin-left:66.66666667%}.flexboxgrid__col-sm-offset-9___24Evy{margin-left:75%}.flexboxgrid__col-sm-offset-10___1-lcE{margin-left:83.33333333%}.flexboxgrid__col-sm-offset-11___2ynFq{margin-left:91.66666667%}.flexboxgrid__start-sm___3Dilu{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-sm___39HWq{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-sm___3B07f{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-sm___1begS{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-sm___Oh4K7{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-sm___1jPnc{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-sm___3ffbb{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-sm___1Rcaf{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-sm___2Gzhb{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-sm___1pF8w{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}@media only screen and (min-width:64em){.flexboxgrid__container___R2zU9{width:65rem}.flexboxgrid__col-md___2lbzm,.flexboxgrid__col-md-1___1Lapj,.flexboxgrid__col-md-2___1c_4t,.flexboxgrid__col-md-3___3ANRS,.flexboxgrid__col-md-4___a_FyK,.flexboxgrid__col-md-5___YXlMq,.flexboxgrid__col-md-6___5OSyJ,.flexboxgrid__col-md-7___1Zp-r,.flexboxgrid__col-md-8___3979J,.flexboxgrid__col-md-9___2fXuC,.flexboxgrid__col-md-10___2Jbee,.flexboxgrid__col-md-11___3drbK,.flexboxgrid__col-md-12___zR2lK,.flexboxgrid__col-md-offset-0___2O3vR,.flexboxgrid__col-md-offset-1___2XNCz,.flexboxgrid__col-md-offset-2___2t-NV,.flexboxgrid__col-md-offset-3___1zlTP,.flexboxgrid__col-md-offset-4___3aHxz,.flexboxgrid__col-md-offset-5___3S2Gw,.flexboxgrid__col-md-offset-6___3KV0V,.flexboxgrid__col-md-offset-7___1OdCD,.flexboxgrid__col-md-offset-8___2vFbQ,.flexboxgrid__col-md-offset-9___1q95x,.flexboxgrid__col-md-offset-10___2CeMK,.flexboxgrid__col-md-offset-11___3u6XW,.flexboxgrid__col-md-offset-12___eKUlL{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-md___2lbzm{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-md-1___1Lapj{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-md-2___1c_4t{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-md-3___3ANRS{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-md-4___a_FyK{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-md-5___YXlMq{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-md-6___5OSyJ{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-md-7___1Zp-r{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-md-8___3979J{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-md-9___2fXuC{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-md-10___2Jbee{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-md-11___3drbK{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-md-12___zR2lK{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-md-offset-0___2O3vR{margin-left:0}.flexboxgrid__col-md-offset-1___2XNCz{margin-left:8.33333333%}.flexboxgrid__col-md-offset-2___2t-NV{margin-left:16.66666667%}.flexboxgrid__col-md-offset-3___1zlTP{margin-left:25%}.flexboxgrid__col-md-offset-4___3aHxz{margin-left:33.33333333%}.flexboxgrid__col-md-offset-5___3S2Gw{margin-left:41.66666667%}.flexboxgrid__col-md-offset-6___3KV0V{margin-left:50%}.flexboxgrid__col-md-offset-7___1OdCD{margin-left:58.33333333%}.flexboxgrid__col-md-offset-8___2vFbQ{margin-left:66.66666667%}.flexboxgrid__col-md-offset-9___1q95x{margin-left:75%}.flexboxgrid__col-md-offset-10___2CeMK{margin-left:83.33333333%}.flexboxgrid__col-md-offset-11___3u6XW{margin-left:91.66666667%}.flexboxgrid__start-md___2B-sg{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-md___3VDfS{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-md___2fJWy{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-md___12FDg{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-md___3wIJR{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-md___2v1cd{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-md___1x54_{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-md___Xn-9x{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-md___3j4t5{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-md___3y72e{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}@media only screen and (min-width:75em){.flexboxgrid__container___R2zU9{width:76rem}.flexboxgrid__col-lg___3SaXd,.flexboxgrid__col-lg-1___2VMiv,.flexboxgrid__col-lg-2___21dKK,.flexboxgrid__col-lg-3___vbACp,.flexboxgrid__col-lg-4___2hzy8,.flexboxgrid__col-lg-5___1-g7-,.flexboxgrid__col-lg-6___21lf8,.flexboxgrid__col-lg-7___3kBG1,.flexboxgrid__col-lg-8___afECx,.flexboxgrid__col-lg-9___10mdl,.flexboxgrid__col-lg-10___1yTfj,.flexboxgrid__col-lg-11___3hMRu,.flexboxgrid__col-lg-12___1rlAA,.flexboxgrid__col-lg-offset-0___3KM3x,.flexboxgrid__col-lg-offset-1___KhvqR,.flexboxgrid__col-lg-offset-2___1ZD_z,.flexboxgrid__col-lg-offset-3___2GQVa,.flexboxgrid__col-lg-offset-4___1zPZj,.flexboxgrid__col-lg-offset-5___Kj8Iq,.flexboxgrid__col-lg-offset-6___3nun3,.flexboxgrid__col-lg-offset-7___YTmn9,.flexboxgrid__col-lg-offset-8___1qG2t,.flexboxgrid__col-lg-offset-9___qd27B,.flexboxgrid__col-lg-offset-10___2YScP,.flexboxgrid__col-lg-offset-11___3pPvj,.flexboxgrid__col-lg-offset-12___2rHEg{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-lg___3SaXd{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-lg-1___2VMiv{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-lg-2___21dKK{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-lg-3___vbACp{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-lg-4___2hzy8{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-lg-5___1-g7-{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-lg-6___21lf8{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-lg-7___3kBG1{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-lg-8___afECx{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-lg-9___10mdl{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-lg-10___1yTfj{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-lg-11___3hMRu{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-lg-12___1rlAA{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-lg-offset-0___3KM3x{margin-left:0}.flexboxgrid__col-lg-offset-1___KhvqR{margin-left:8.33333333%}.flexboxgrid__col-lg-offset-2___1ZD_z{margin-left:16.66666667%}.flexboxgrid__col-lg-offset-3___2GQVa{margin-left:25%}.flexboxgrid__col-lg-offset-4___1zPZj{margin-left:33.33333333%}.flexboxgrid__col-lg-offset-5___Kj8Iq{margin-left:41.66666667%}.flexboxgrid__col-lg-offset-6___3nun3{margin-left:50%}.flexboxgrid__col-lg-offset-7___YTmn9{margin-left:58.33333333%}.flexboxgrid__col-lg-offset-8___1qG2t{margin-left:66.66666667%}.flexboxgrid__col-lg-offset-9___qd27B{margin-left:75%}.flexboxgrid__col-lg-offset-10___2YScP{margin-left:83.33333333%}.flexboxgrid__col-lg-offset-11___3pPvj{margin-left:91.66666667%}.flexboxgrid__start-lg___ageu9{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-lg___3H3SI{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-lg___27_fM{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-lg___1tWWw{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-lg___nocGI{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-lg___IYGks{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-lg___zZC2C{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-lg___2njzk{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-lg___6dksO{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-lg___xGBvS{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}a{color:#ff4081;text-decoration:none;} a.no-decor{color:inherit !important;} a:hover{text-decoration:underline;} a.no-decor:hover{text-decoration:none;} html{font-family:'Roboto',sans-serif;-webkit-font-smoothing:antialiased;} body{background-color:#efefef;} body, 2 | h1, 3 | h2, 4 | h3, 5 | h4, 6 | h5, 7 | h6{margin:0;color:rgba(0, 0, 0, 0.87);} h1, 8 | h2, 9 | h3, 10 | h4, 11 | h5, 12 | h6{font-weight:300;} body{font-size:15px;line-height:24px;} strong, 13 | b{font-weight:500;} 14 | /*# sourceMappingURL=styles.main.css.map */ 15 | -------------------------------------------------------------------------------- /resources/public/css/styles.main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"styles.main.css", 4 | "lineCount":13, 5 | "mappings":"A,qwiBCGAA,C,sCAKAA,CAACC,S,4BAIDD,CAACE,M,6BAIDF,CAACC,SAASC,M,wBAIVC,I,sEAKAC,I,4BAIAA,I;AAAMC,E;AAAIC,E;AAAIC,E;AAAIC,E;AAAIC,E;AAAIC,E,sCAK1BL,E;AAAIC,E;AAAIC,E;AAAIC,E;AAAIC,E;AAAIC,E,mBAIpBN,I,mCAKAO,M;AAAQC;", 6 | "sources":["jar:file:/Users/matus/.m2/repository/cljsjs/react-flexbox-grid/0.10.2-1/react-flexbox-grid-0.10.2-1.jar!/cljsjs/react-flexbox-grid/production/react-flexbox-grid.min.inc.css","styles.main.less"], 7 | "sourcesContent":[".flexboxgrid__container-fluid___2lUES,.flexboxgrid__container___R2zU9{margin-right:auto;margin-left:auto}.flexboxgrid__container-fluid___2lUES{padding-right:2rem;padding-left:2rem}.flexboxgrid__row___1y_mg{box-sizing:border-box;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-0.5rem;margin-left:-0.5rem}.flexboxgrid__row___1y_mg.flexboxgrid__reverse___1X682{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flexboxgrid__col___3RqPP.flexboxgrid__reverse___1X682{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flexboxgrid__col-xs___1ROHR,.flexboxgrid__col-xs-1___VtNIK,.flexboxgrid__col-xs-2___36nDa,.flexboxgrid__col-xs-3___2f2Ql,.flexboxgrid__col-xs-4___TxBJg,.flexboxgrid__col-xs-5___1HkK5,.flexboxgrid__col-xs-6___1DhV6,.flexboxgrid__col-xs-7___3o2m-,.flexboxgrid__col-xs-8___3ARGc,.flexboxgrid__col-xs-9___15qfl,.flexboxgrid__col-xs-10___2AWNv,.flexboxgrid__col-xs-11___3H-6F,.flexboxgrid__col-xs-12___phbtE,.flexboxgrid__col-xs-offset-0___10C7E,.flexboxgrid__col-xs-offset-1___12o_R,.flexboxgrid__col-xs-offset-2___2Hh-B,.flexboxgrid__col-xs-offset-3___8NCys,.flexboxgrid__col-xs-offset-4___dA0P1,.flexboxgrid__col-xs-offset-5___2MbdF,.flexboxgrid__col-xs-offset-6___3N3bt,.flexboxgrid__col-xs-offset-7___1yQDG,.flexboxgrid__col-xs-offset-8___2aEcW,.flexboxgrid__col-xs-offset-9___2haBv,.flexboxgrid__col-xs-offset-10___1QsVg,.flexboxgrid__col-xs-offset-11___29xQn,.flexboxgrid__col-xs-offset-12___1XWFb{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-xs___1ROHR{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-xs-1___VtNIK{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-xs-2___36nDa{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-xs-3___2f2Ql{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-xs-4___TxBJg{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-xs-5___1HkK5{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-xs-6___1DhV6{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-xs-7___3o2m-{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-xs-8___3ARGc{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-xs-9___15qfl{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-xs-10___2AWNv{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-xs-11___3H-6F{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-xs-12___phbtE{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-xs-offset-0___10C7E{margin-left:0}.flexboxgrid__col-xs-offset-1___12o_R{margin-left:8.33333333%}.flexboxgrid__col-xs-offset-2___2Hh-B{margin-left:16.66666667%}.flexboxgrid__col-xs-offset-3___8NCys{margin-left:25%}.flexboxgrid__col-xs-offset-4___dA0P1{margin-left:33.33333333%}.flexboxgrid__col-xs-offset-5___2MbdF{margin-left:41.66666667%}.flexboxgrid__col-xs-offset-6___3N3bt{margin-left:50%}.flexboxgrid__col-xs-offset-7___1yQDG{margin-left:58.33333333%}.flexboxgrid__col-xs-offset-8___2aEcW{margin-left:66.66666667%}.flexboxgrid__col-xs-offset-9___2haBv{margin-left:75%}.flexboxgrid__col-xs-offset-10___1QsVg{margin-left:83.33333333%}.flexboxgrid__col-xs-offset-11___29xQn{margin-left:91.66666667%}.flexboxgrid__start-xs___h8qdA{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-xs___1JWon{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-xs___33Mku{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-xs___UhA-V{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-xs___1h5t3{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-xs___2tRUa{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-xs___1okkK{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-xs___WFP84{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-xs___XoosK{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-xs___HnlRw{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}@media only screen and (min-width:48em){.flexboxgrid__container___R2zU9{width:49rem}.flexboxgrid__col-sm___3tZ-z,.flexboxgrid__col-sm-1___2Gca6,.flexboxgrid__col-sm-2___YETza,.flexboxgrid__col-sm-3___2irZQ,.flexboxgrid__col-sm-4___3kj7S,.flexboxgrid__col-sm-5___gAxuQ,.flexboxgrid__col-sm-6___vUdKH,.flexboxgrid__col-sm-7___22IcQ,.flexboxgrid__col-sm-8___2_YhB,.flexboxgrid__col-sm-9___2ubpx,.flexboxgrid__col-sm-10___262G9,.flexboxgrid__col-sm-11___39s7J,.flexboxgrid__col-sm-12___1e5Uk,.flexboxgrid__col-sm-offset-0___llQ6-,.flexboxgrid__col-sm-offset-1___1PFWu,.flexboxgrid__col-sm-offset-2___1DgbO,.flexboxgrid__col-sm-offset-3___3W5Iv,.flexboxgrid__col-sm-offset-4___3YToG,.flexboxgrid__col-sm-offset-5___609Vo,.flexboxgrid__col-sm-offset-6___TCeVQ,.flexboxgrid__col-sm-offset-7___csvBu,.flexboxgrid__col-sm-offset-8___11PYH,.flexboxgrid__col-sm-offset-9___24Evy,.flexboxgrid__col-sm-offset-10___1-lcE,.flexboxgrid__col-sm-offset-11___2ynFq,.flexboxgrid__col-sm-offset-12___3MBMi{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-sm___3tZ-z{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-sm-1___2Gca6{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-sm-2___YETza{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-sm-3___2irZQ{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-sm-4___3kj7S{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-sm-5___gAxuQ{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-sm-6___vUdKH{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-sm-7___22IcQ{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-sm-8___2_YhB{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-sm-9___2ubpx{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-sm-10___262G9{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-sm-11___39s7J{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-sm-12___1e5Uk{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-sm-offset-0___llQ6-{margin-left:0}.flexboxgrid__col-sm-offset-1___1PFWu{margin-left:8.33333333%}.flexboxgrid__col-sm-offset-2___1DgbO{margin-left:16.66666667%}.flexboxgrid__col-sm-offset-3___3W5Iv{margin-left:25%}.flexboxgrid__col-sm-offset-4___3YToG{margin-left:33.33333333%}.flexboxgrid__col-sm-offset-5___609Vo{margin-left:41.66666667%}.flexboxgrid__col-sm-offset-6___TCeVQ{margin-left:50%}.flexboxgrid__col-sm-offset-7___csvBu{margin-left:58.33333333%}.flexboxgrid__col-sm-offset-8___11PYH{margin-left:66.66666667%}.flexboxgrid__col-sm-offset-9___24Evy{margin-left:75%}.flexboxgrid__col-sm-offset-10___1-lcE{margin-left:83.33333333%}.flexboxgrid__col-sm-offset-11___2ynFq{margin-left:91.66666667%}.flexboxgrid__start-sm___3Dilu{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-sm___39HWq{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-sm___3B07f{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-sm___1begS{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-sm___Oh4K7{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-sm___1jPnc{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-sm___3ffbb{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-sm___1Rcaf{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-sm___2Gzhb{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-sm___1pF8w{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}@media only screen and (min-width:64em){.flexboxgrid__container___R2zU9{width:65rem}.flexboxgrid__col-md___2lbzm,.flexboxgrid__col-md-1___1Lapj,.flexboxgrid__col-md-2___1c_4t,.flexboxgrid__col-md-3___3ANRS,.flexboxgrid__col-md-4___a_FyK,.flexboxgrid__col-md-5___YXlMq,.flexboxgrid__col-md-6___5OSyJ,.flexboxgrid__col-md-7___1Zp-r,.flexboxgrid__col-md-8___3979J,.flexboxgrid__col-md-9___2fXuC,.flexboxgrid__col-md-10___2Jbee,.flexboxgrid__col-md-11___3drbK,.flexboxgrid__col-md-12___zR2lK,.flexboxgrid__col-md-offset-0___2O3vR,.flexboxgrid__col-md-offset-1___2XNCz,.flexboxgrid__col-md-offset-2___2t-NV,.flexboxgrid__col-md-offset-3___1zlTP,.flexboxgrid__col-md-offset-4___3aHxz,.flexboxgrid__col-md-offset-5___3S2Gw,.flexboxgrid__col-md-offset-6___3KV0V,.flexboxgrid__col-md-offset-7___1OdCD,.flexboxgrid__col-md-offset-8___2vFbQ,.flexboxgrid__col-md-offset-9___1q95x,.flexboxgrid__col-md-offset-10___2CeMK,.flexboxgrid__col-md-offset-11___3u6XW,.flexboxgrid__col-md-offset-12___eKUlL{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-md___2lbzm{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-md-1___1Lapj{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-md-2___1c_4t{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-md-3___3ANRS{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-md-4___a_FyK{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-md-5___YXlMq{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-md-6___5OSyJ{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-md-7___1Zp-r{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-md-8___3979J{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-md-9___2fXuC{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-md-10___2Jbee{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-md-11___3drbK{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-md-12___zR2lK{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-md-offset-0___2O3vR{margin-left:0}.flexboxgrid__col-md-offset-1___2XNCz{margin-left:8.33333333%}.flexboxgrid__col-md-offset-2___2t-NV{margin-left:16.66666667%}.flexboxgrid__col-md-offset-3___1zlTP{margin-left:25%}.flexboxgrid__col-md-offset-4___3aHxz{margin-left:33.33333333%}.flexboxgrid__col-md-offset-5___3S2Gw{margin-left:41.66666667%}.flexboxgrid__col-md-offset-6___3KV0V{margin-left:50%}.flexboxgrid__col-md-offset-7___1OdCD{margin-left:58.33333333%}.flexboxgrid__col-md-offset-8___2vFbQ{margin-left:66.66666667%}.flexboxgrid__col-md-offset-9___1q95x{margin-left:75%}.flexboxgrid__col-md-offset-10___2CeMK{margin-left:83.33333333%}.flexboxgrid__col-md-offset-11___3u6XW{margin-left:91.66666667%}.flexboxgrid__start-md___2B-sg{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-md___3VDfS{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-md___2fJWy{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-md___12FDg{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-md___3wIJR{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-md___2v1cd{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-md___1x54_{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-md___Xn-9x{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-md___3j4t5{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-md___3y72e{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}@media only screen and (min-width:75em){.flexboxgrid__container___R2zU9{width:76rem}.flexboxgrid__col-lg___3SaXd,.flexboxgrid__col-lg-1___2VMiv,.flexboxgrid__col-lg-2___21dKK,.flexboxgrid__col-lg-3___vbACp,.flexboxgrid__col-lg-4___2hzy8,.flexboxgrid__col-lg-5___1-g7-,.flexboxgrid__col-lg-6___21lf8,.flexboxgrid__col-lg-7___3kBG1,.flexboxgrid__col-lg-8___afECx,.flexboxgrid__col-lg-9___10mdl,.flexboxgrid__col-lg-10___1yTfj,.flexboxgrid__col-lg-11___3hMRu,.flexboxgrid__col-lg-12___1rlAA,.flexboxgrid__col-lg-offset-0___3KM3x,.flexboxgrid__col-lg-offset-1___KhvqR,.flexboxgrid__col-lg-offset-2___1ZD_z,.flexboxgrid__col-lg-offset-3___2GQVa,.flexboxgrid__col-lg-offset-4___1zPZj,.flexboxgrid__col-lg-offset-5___Kj8Iq,.flexboxgrid__col-lg-offset-6___3nun3,.flexboxgrid__col-lg-offset-7___YTmn9,.flexboxgrid__col-lg-offset-8___1qG2t,.flexboxgrid__col-lg-offset-9___qd27B,.flexboxgrid__col-lg-offset-10___2YScP,.flexboxgrid__col-lg-offset-11___3pPvj,.flexboxgrid__col-lg-offset-12___2rHEg{box-sizing:border-box;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;padding-right:.5rem;padding-left:.5rem}.flexboxgrid__col-lg___3SaXd{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-preferred-size:0;flex-basis:0;max-width:100%}.flexboxgrid__col-lg-1___2VMiv{-ms-flex-preferred-size:8.33333333%;flex-basis:8.33333333%;max-width:8.33333333%}.flexboxgrid__col-lg-2___21dKK{-ms-flex-preferred-size:16.66666667%;flex-basis:16.66666667%;max-width:16.66666667%}.flexboxgrid__col-lg-3___vbACp{-ms-flex-preferred-size:25%;flex-basis:25%;max-width:25%}.flexboxgrid__col-lg-4___2hzy8{-ms-flex-preferred-size:33.33333333%;flex-basis:33.33333333%;max-width:33.33333333%}.flexboxgrid__col-lg-5___1-g7-{-ms-flex-preferred-size:41.66666667%;flex-basis:41.66666667%;max-width:41.66666667%}.flexboxgrid__col-lg-6___21lf8{-ms-flex-preferred-size:50%;flex-basis:50%;max-width:50%}.flexboxgrid__col-lg-7___3kBG1{-ms-flex-preferred-size:58.33333333%;flex-basis:58.33333333%;max-width:58.33333333%}.flexboxgrid__col-lg-8___afECx{-ms-flex-preferred-size:66.66666667%;flex-basis:66.66666667%;max-width:66.66666667%}.flexboxgrid__col-lg-9___10mdl{-ms-flex-preferred-size:75%;flex-basis:75%;max-width:75%}.flexboxgrid__col-lg-10___1yTfj{-ms-flex-preferred-size:83.33333333%;flex-basis:83.33333333%;max-width:83.33333333%}.flexboxgrid__col-lg-11___3hMRu{-ms-flex-preferred-size:91.66666667%;flex-basis:91.66666667%;max-width:91.66666667%}.flexboxgrid__col-lg-12___1rlAA{-ms-flex-preferred-size:100%;flex-basis:100%;max-width:100%}.flexboxgrid__col-lg-offset-0___3KM3x{margin-left:0}.flexboxgrid__col-lg-offset-1___KhvqR{margin-left:8.33333333%}.flexboxgrid__col-lg-offset-2___1ZD_z{margin-left:16.66666667%}.flexboxgrid__col-lg-offset-3___2GQVa{margin-left:25%}.flexboxgrid__col-lg-offset-4___1zPZj{margin-left:33.33333333%}.flexboxgrid__col-lg-offset-5___Kj8Iq{margin-left:41.66666667%}.flexboxgrid__col-lg-offset-6___3nun3{margin-left:50%}.flexboxgrid__col-lg-offset-7___YTmn9{margin-left:58.33333333%}.flexboxgrid__col-lg-offset-8___1qG2t{margin-left:66.66666667%}.flexboxgrid__col-lg-offset-9___qd27B{margin-left:75%}.flexboxgrid__col-lg-offset-10___2YScP{margin-left:83.33333333%}.flexboxgrid__col-lg-offset-11___3pPvj{margin-left:91.66666667%}.flexboxgrid__start-lg___ageu9{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;text-align:start}.flexboxgrid__center-lg___3H3SI{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-align:center}.flexboxgrid__end-lg___27_fM{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;text-align:end}.flexboxgrid__top-lg___1tWWw{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.flexboxgrid__middle-lg___nocGI{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.flexboxgrid__bottom-lg___IYGks{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.flexboxgrid__around-lg___zZC2C{-ms-flex-pack:distribute;justify-content:space-around}.flexboxgrid__between-lg___2njzk{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.flexboxgrid__first-lg___6dksO{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.flexboxgrid__last-lg___xGBvS{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}","@import (inline) \"cljsjs/react-flexbox-grid/production/react-flexbox-grid.min.inc.css\";\n\n\na {\n color: #ff4081;\n text-decoration: none;\n}\n\na.no-decor {\n color: inherit !important;\n}\n\na:hover {\n text-decoration: underline;\n}\n\na.no-decor:hover {\n text-decoration: none;\n}\n\nhtml {\n font-family: 'Roboto', sans-serif;\n -webkit-font-smoothing: antialiased;\n}\n\nbody {\n background-color: #efefef;\n}\n\nbody, h1, h2, h3, h4, h5, h6 {\n margin: 0;\n color: rgba(0,0,0,.87);\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-weight: 300;\n}\n\nbody {\n font-size: 15px;\n line-height: 24px;\n}\n\nstrong, b {\n font-weight: 500;\n}\n"], 8 | "names":["a",".no-decor",":hover","html","body","h1","h2","h3","h4","h5","h6","strong","b"] 9 | } 10 | -------------------------------------------------------------------------------- /clojurescript-ethereum-example.iml: -------------------------------------------------------------------------------- 1 | 2 |