Formatting

Formatting

--- src/cljs/learn_specter/app.cljs
+++ src/cljs/learn_specter/app.cljs
@@ -9,7 +9,6 @@
             [learn-specter.subs :as subs]
             [learn-specter.handlers :as handlers]
             [devtools.core :as devtools]))
-

 ;; Components


Option to omit annotations from PGN input.

--- src/clojure/clj_chess/game.cljc
+++ src/clojure/clj_chess/game.cljc
@@ -654,6 +654,8 @@

 (defn from-pgn
   "Creates a game from a PGN string."
-  [pgn-string]
+  [pgn-string & {:keys [include-annotations?]
+                 :or {:include-annotations? true}}]
   (from-ecn (pgn/parse-pgn pgn-string)
-            :san true))
+            :san true
+            :include-annotations? include-annotations?))


print declares in core

print declares in core

--- src/com/billpiel/sayid/core.clj
+++ src/com/billpiel/sayid/core.clj
@@ -36,9 +36,11 @@
   such as `ws-print`."
   (atom default-printer))

+(declare with-printer)
 (declare ws-query*)
 (declare ws-query)
 (declare ws-print)
+(declare trees-print)

 ;; === Helper functions

@@ -372,6 +374,15 @@
                                  (keys v)
                                  (meta v)))))))

+(defn mk-printer
+  [opts]
+  (cond
+    (nil? opts) default-printer
+
+    (-> opts first (= :-))
+    (mk-printer-black-list (rest opts))
+
+    :else (mk-printer-white-list opts)))

 (defmacro with-this-printer
   "Sets the printer as `prn` for the lexical scope. `prn` may be a
@@ -460,16 +471,6 @@
                      default-printer
                      false))

-(defn mk-printer
-  [opts]
-  (cond
-    (nil? opts) default-printer
-
-    (-> opts first (= :-))
-    (mk-printer-black-list (rest opts))
-
-    :else (mk-printer-white-list opts)))
-
 (defn set-printer!
   "Sets the printer that is applied by `with-printer` and used by print
   functions such as `ws-print`."


Var documentation

Var documentation

--- src/com/hypirion/clj_xchart.clj
+++ src/com/hypirion/clj_xchart.clj
@@ -34,6 +34,10 @@
                      GridLayout)))

 (def colors
+  "All the default java.awt colors as keywords. You can use this map
+  to iterate over the keys, in case you'd like to compare different
+  colors. Or you could use java.awt.Color directly to use the exact
+  color you want."
   {:blue Color/BLUE
    :black Color/BLACK
    :cyan Color/CYAN
@@ -49,6 +53,9 @@
    :yellow Color/YELLOW})

 (def markers
+  "All the default XChart markers as keywords. To create your own marker, you
+  must _subclass_ the org.knowm.xchart.style.markers.Marker class, so it's often
+  better to use the default ones."
   {:circle (Circle.)
    :diamond (Diamond.)
    :none (None.)
@@ -57,20 +64,25 @@
    :triangle-down (TriangleDown.)})

 (def xy-render-styles
+  "The different xy-render styles: :area, :scatter and :line."
   {:area XYSeries$XYSeriesRenderStyle/Area
    :scatter XYSeries$XYSeriesRenderStyle/Scatter
    :line XYSeries$XYSeriesRenderStyle/Line})

 (def pie-render-styles
+  "The different pie render styles. It is :pie by default."
   {:pie PieSeries$PieSeriesRenderStyle/Pie
    :donut PieSeries$PieSeriesRenderStyle/Donut})

 (def pie-annotation-types
+  "The different annotation types you can use to annotate pie charts.
+  By default, this is :percentage."
   {:label PieStyler$AnnotationType/Label
    :label-and-percentage PieStyler$AnnotationType/LabelAndPercentage
    :percentage PieStyler$AnnotationType/Percentage})

 (def category-render-styles
+  "The different styles you can use for category series."
   {:area CategorySeries$CategorySeriesRenderStyle/Area
    :bar CategorySeries$CategorySeriesRenderStyle/Bar
    :line CategorySeries$CategorySeriesRenderStyle/Line
@@ -78,15 +90,20 @@
    :stick CategorySeries$CategorySeriesRenderStyle/Stick})

 (def bubble-render-styles
+  "Different render styles for bubble series. For now this is useless, as you
+  can only use :round. Apparently :box is around the corner though."
   {:round BubbleSeries$BubbleSeriesRenderStyle/Round})

 (def text-alignments
+  "The different kinds of text alignments you can use."
   {:centre Styler$TextAlignment/Centre
    :left Styler$TextAlignment/Left
    :right Styler$TextAlignment/Right})

 (def legend-positions
-  {:inside-n Styler$LegendPosition/InsideN
+  "The different legend positions. Note that xchart implements only a
+  subset of inside/outside for the different positions."
+  {:inside-n  Styler$LegendPosition/InsideN
    :inside-ne Styler$LegendPosition/InsideNE
    :inside-nw Styler$LegendPosition/InsideNW
    :inside-se Styler$LegendPosition/InsideSW
@@ -94,6 +111,7 @@
    :outside-e Styler$LegendPosition/OutsideE})

 (def themes
+  "The different default themes you can use with xchart."
   {:ggplot2 (GGPlot2Theme.)
    :matlab (MatlabTheme.)
    :xchart (XChartTheme.)})


Check for :last-vote-timestamp in validations since hasn't been cast to :lastVoteTimestamp till when it get formatted just before upload

--- src/polismath/conv_man.clj
+++ src/polismath/conv_man.clj
@@ -148,11 +148,11 @@
 ;; Also, should place this in conversation, but for now...
 (def Conversation
   "A schema for what valid conversations should look like (WIP)"
-  {:zid               s/Int
-   :lastVoteTimestamp s/Int
-   :group-votes       s/Any
+  {:zid                 s/Int
+   :last-vote-timestamp s/Int
+   :group-votes         s/Any
    ;; Note: we let all other key-value pairs pass through
-   s/Keyword          s/Any})
+   s/Keyword            s/Any})

 (defn update-fn
   "This function is what actually gets sent to the conv-actor. In addition to the conversation and vote batches


remove likely unecessary thread/sleep in conv-man

--- src/polismath/conv_man.clj
+++ src/polismath/conv_man.clj
@@ -147,9 +147,6 @@
       (catch Exception e
         ;; XXX See comment below about decoupling errors
         (error-callback votes start-time (:opts' conv) e)
-        ; Wait a second before returning the origin, unmodified conv, to throttle retries
-        ;; XXX This shouldn't be here... ???
-        (Thread/sleep 1000)
         conv))))


set alarm

set alarm

--- src/cljs/app/core.cljs
+++ src/cljs/app/core.cljs
@@ -66,7 +66,7 @@
               expire? #(< % expires)]
           (doseq [[id recent] active-devices
                   :when (expire? recent)]
-            #_ (if alarm (alarm))
+            (if alarm (alarm))
             (println "[EXPIRED]" id expires recent))
           (recur (assoc (apply dissoc active-devices
                                (remove (comp expire? second)


Improve frontend tests

Improve frontend tests

--- test/cljs/reitit/frontend/core_test.cljs
+++ test/cljs/reitit/frontend/core_test.cljs
@@ -40,12 +40,13 @@
       (is (= "/foo"
              (r/match->path (rf/match-by-name router ::foo))))

-      (is (= [{:type :warn
-               :message ["missing route" ::asd]}]
-             (:messages
-               (capture-console
-                 (fn []
-                   (rf/match-by-name! router ::asd))))))))
+      (testing "console warning about missing route"
+        (is (= [{:type :warn
+                 :message ["missing route" ::asd]}]
+               (:messages
+                 (capture-console
+                   (fn []
+                     (rf/match-by-name! router ::asd)))))))))

   (testing "schema coercion"
     (let [router (r/router ["/"
@@ -54,6 +55,7 @@
                                                  :query {(s/optional-key :mode) s/Keyword}}}]]
                            {:compile rc/compile-request-coercers
                             :data {:coercion rsc/coercion}})]
+
       (is (= (r/map->Match
                {:template "/:id"
                 :path-params {:id "5"}
@@ -65,25 +67,36 @@
       (is (= "/5"
              (r/match->path (rf/match-by-name router ::foo {:id 5}))))

-      (is (= (r/map->Match
-               {:template "/:id"
-                :path-params {:id "5"}
-                ;; Note: query not included in path
-                :path "/5"
-                :parameters {:path {:id 5}
-                             :query {:mode :foo}}})
-             (m (rf/match-by-path router "/5?mode=foo"))))
+      (testing "query param is read"
+        (is (= (r/map->Match
+                 {:template "/:id"
+                  :path-params {:id "5"}
+                  ;; Note: query not included in path
+                  :path "/5"
+                  :parameters {:path {:id 5}
+                               :query {:mode :foo}}})
+               (m (rf/match-by-path router "/5?mode=foo"))))

-      (is (= "/5?mode=foo"
-             (r/match->path (rf/match-by-name router ::foo {:id 5}) {:mode :foo})))
+        (is (= "/5?mode=foo"
+               (r/match->path (rf/match-by-name router ::foo {:id 5}) {:mode :foo}))))

-      (is (= [{:type :warn
-               :message ["missing path-params for route" ::foo
-                         {:template "/:id"
-                          :missing #{:id}
-                          :required #{:id}
-                          :path-params {}}]}]
-             (:messages
-               (capture-console
-                 (fn []
-                   (rf/match-by-name! router ::foo {})))))))))
+      (testing "fragment is ignored"
+        (is (= (r/map->Match
+                 {:template "/:id"
+                  :path-params {:id "5"}
+                  :path "/5"
+                  :parameters {:path {:id 5}
+                               :query {:mode :foo}}})
+               (m (rf/match-by-path router "/5?mode=foo#fragment")))))
+
+      (testing "console warning about missing params"
+        (is (= [{:type :warn
+                 :message ["missing path-params for route" ::foo
+                           {:template "/:id"
+                            :missing #{:id}
+                            :required #{:id}
+                            :path-params {}}]}]
+               (:messages
+                 (capture-console
+                   (fn []
+                     (rf/match-by-name! router ::foo {}))))))))))


ignoring input and adding 100 (bypassing proxmox non valid id)

--- src/proxmox/generators.clj
+++ src/proxmox/generators.clj
@@ -21,16 +21,16 @@
   []
   (loop [i 5]
     (when (> i 0)
-      (let [id (gen-ct-id)]
+      (let [id (+ 100 (gen-ct-id))]
+        (debug id)
         (if-not (ct-exists id)
           id
           (recur (- i 1)))))))

 (defn ct-id
   "Generates a container id"
-  [id]
-   (if (ct-exists id)
-    (if-let [gid (try-gen)]
+  [_]
+   (if-let [gid (try-gen)]
       gid
-     (throw+ {:type :id-gen-error} "Failed to generate id for container"))))
+     (throw+ {:type :id-gen-error} "Failed to generate id for container")))


Handle uncaught exceptions in participant poller

--- src/rpi_challenger/app.clj
+++ src/rpi_challenger/app.clj
@@ -68,7 +68,12 @@

 (defn ^:dynamic poll-participant-loop [app participant]
   (while (not (Thread/interrupted))
-    (poll-participant app participant (t/generate-challenges (:tournament @app)))))
+    (try
+      (poll-participant app participant (t/generate-challenges (:tournament @app)))
+      (catch InterruptedException e
+        (.interrupt (Thread/currentThread)))
+      (catch Throwable e
+        (.error logger (str "Unhandled error in polling participant " (:url participant)) e)))))

 (defn ^:dynamic start-polling [app participant]
   (threads/execute (:thread-pool @app) #(poll-participant-loop app participant)))


Added some code to ladder test script

Added some code to ladder test script

--- clojure/org/gavrog/clojure/test.clj
+++ clojure/org/gavrog/clojure/test.clj
@@ -2,9 +2,18 @@

 (def G (first (iterator-seq (org.gavrog.joss.pgraphs.io.Net/iterator "x.cgd"))))
 (def C (.getGraph (first (.connectedComponents G))))
-(def M (.minimalImage C))
+(def M (-> C .minimalImage .canonical))
 (def nodes (iterator-seq (.nodes M)))
 (def I (org.gavrog.joss.geometry.Operator/identity 3))

 (def phi
   (org.gavrog.joss.pgraphs.basic.Morphism. (nth nodes 0) (nth nodes 1) I))
+
+
+(def L (first (iterator-seq (org.gavrog.joss.pgraphs.io.Net/iterator
+                              "ladder-1d.cgd"))))
+(def nodes (iterator-seq (.nodes L)))
+(def I (org.gavrog.joss.geometry.Operator/identity 1))
+
+(def phi
+  (org.gavrog.joss.pgraphs.basic.Morphism. (nth nodes 0) (nth nodes 1) I))


Changed atom original format back to ISO-SMAP.

--- src/cmr/search/results_handlers/atom_results_handler.clj
+++ src/cmr/search/results_handlers/atom_results_handler.clj
@@ -21,7 +21,7 @@
 (def metadata-format->atom-original-format
   "Defines the concept metadata format to atom original-format mapping"
   {"echo10" "ECHO10"
-   "iso-smap" "SMAP_ISO"
+   "iso-smap" "ISO-SMAP"
    "iso19115" "ISO19115"
    "dif" "DIF"})


www/render.clj: proxy StringTemplateGroup

To find template files in subdirectory, regardless
of its location on classpath.

--- src/org/altlaw/www/render.clj
+++ src/org/altlaw/www/render.clj
@@ -50,19 +50,16 @@
                                    "Foo: $user:{f$it.foo$}$")
                                   {:user [{:foo 1} {:foo 2} {:foo 3}]})))))

-(defn www-templates-dir []
-  (some
-   (fn [dir]
-     (let [template-dir
-           (java/file dir "org" "altlaw" "www" "templates")]
-       (when (.exists template-dir) template-dir)))
-   (cp/classpath-directories)))
+(defn get-string-template-group []
+  (proxy [StringTemplateGroup]
+      ["org.altlaw.www.templates"]
+    (getFileNameFromTemplateName [template-name]
+      (str "org/altlaw/www/templates/" template-name ".st"))))

 (def #^{:private true} template-group
      (sing/global-singleton
       (fn []
-        (let [page-templates (StringTemplateGroup. "org.altlaw.www.templates"
-                                                   (str (www-templates-dir)))]
+        (let [page-templates (get-string-template-group)]
           ;; By default, templates are never refreshed.
           ;; In development mode, always refresh.
           (when (= (context/altlaw-env) "development")


Update Debug information

Update Debug information

--- src/discuss/debug.cljs
+++ src/discuss/debug.cljs
@@ -29,13 +29,21 @@
                (dom/div #js {:className "collapse in well"
                              :id "collapse-debug"}

-                        (dom/h6 nil "Last API call")
-                        (dom/pre nil (get-in data [:debug :last-api]))
+                        (dom/h6 nil "API Calls")
+                        (dom/div #js {:className "padding-bottom"}
+                                 (dom/div #js {:className "form-group"}
+                                          (dom/input #js {:id          (lib/prefix-name "debug-api-call")
+                                                          :className   "form-control"
+                                                          :placeholder (get-in data [:debug :last-api])}))
+                                 (dom/button #js {:className "btn btn-default"
+                                                  :onClick   #(discuss.communication/ajax-get (lib/get-value-by-id "debug-api-call"))}
+                                             "Make new API call"))
+
+                        ;; Fast login
+                        (dom/h6 nil "Other")
                         (dom/button #js {:className "btn btn-default"
                                          :onClick   #(discuss.communication/ajax-get (get-in data [:debug :last-api]))}
                                     "Resend API Call")
-
-                        ;; Fast login
                         " "
                         (dom/button #js {:className "btn btn-default"
                                          :onClick   #(discuss.auth/login "christian" "christian")}


Removed webserver

Removed webserver

--- src/edge/webserver.clj
+++ src/edge/webserver.clj
@@ -12,24 +12,5 @@
    [schema.core :as s]
    [yada.yada :refer [yada resource]]))

-(defn make-api []
-  ["/"
-   [["" (redirect "index.html")]
-    ["favicon.ico" (yada nil)]
-    ["" (yada (io/file "target/dev"))]]])
+;; TODO: Create a Webserver record here

-(s/defrecord Webserver [port :- (s/pred integer? "must be a port number")]
-  Lifecycle
-  (start [component]
-    (assoc component
-           :server (http/start-server (make-handler (make-api)) component)))
-
-  (stop [component]
-    (when-let [server (:server component)] (.close server))
-    component))
-
-(defn new-webserver []
-  (using
-   (map->Webserver {:port 3000})
-   []))
-


Adapt to httpurr changes.

Adapt to httpurr changes.


Add some move-sequence tests

Add some move-sequence tests

--- test/tile_game/board_test.clj
+++ test/tile_game/board_test.clj
@@ -93,5 +93,10 @@
   (is (last-on-row? a-board (goal-coord a-board 0)))
   (is (not (last-on-row? a-board (goal-coord a-board 1)))))

+(deftest move-a-sequence
+  (is (= (move-sequence a-board [5 [2 0] #{}]) '(2 3 5)))
+  (is (= (move-sequence a-board [5 [2 0] #{}] [4 [1 0] #{5}])
+         '(2 3 5 2 3 1 4 3 1 4))))
+
 ;; (deftest solution-for-tile
 ;;   (is (= (solve-tile a-board 5) '(5))))


Owls fly away upwards now!!111!

Owls fly away upwards now!!111!

--- src/kindness/core.cljs
+++ src/kindness/core.cljs
@@ -129,7 +129,7 @@
         laser (make-entity [:laser {:position [(- x 48) (+ y 10)]
                                     :bounds [48 2]
                                     :color "#3C6890"
-                                    :velocity -0.4}])
+                                    :velocity [-0.4 0]}])
         new-entity (assoc-in entity [:components :weaponised :laser :last] now)]
     (replace-entity new-entity)
     (insert-entity laser)))
@@ -282,9 +282,9 @@
    (if (> y 100) 0 y)])

 (defn new-position
-  [[x y] velocity delta]
-  [(+ x (* delta velocity))
-   y])
+  [[x y] [dx dy] delta]
+  [(+ x (* delta dx))
+   (+ y (* delta dy))])

 (defn end-game!
   []
@@ -329,7 +329,7 @@

 (defn trigger-entity!
   [entity]
-  (replace-entity (assoc-in entity [:components :movable :velocity] 0.5)))
+  (replace-entity (assoc-in entity [:components :movable :velocity] [0 -0.5])))

 (defn try-activate!
   []


3/4 of the way to a working socket-based repl task. Take that, Ant!

--- src/leiningen/repl.clj
+++ src/leiningen/repl.clj
@@ -1,9 +1,48 @@
 (ns leiningen.repl
   (:require [clojure.main])
-  (:use [leiningen.compile :only [eval-in-project]]))
+  (:use [leiningen.compile :only [eval-in-project]]
+        [clojure.java.io :only [copy]])
+  (:import [java.net Socket]
+           [java.io OutputStreamWriter InputStreamReader]))
+
+(defn repl-form [project port]
+  (let [init-form (and (:main project)
+                       [:init `#(doto '~(:main project) require in-ns)])]
+    `(do (ns ~'user
+           (:use [~'clojure.main :only [~'repl]])
+           (:import [java.net ~'InetAddress ~'ServerSocket ~'Socket
+                     ~'SocketException]
+                    [java.io ~'InputStreamReader ~'OutputStream
+                     ~'OutputStreamWriter ~'PrintWriter]
+                    [clojure.lang ~'LineNumberingPushbackReader]))
+         (println "Opening connection on port" ~port)
+         (let [server# (ServerSocket. ~port)
+               socket# (.accept server#)
+               ins# (.getInputStream socket#)
+               outs# (.getOutputStream socket#)]
+           (binding [*in* (-> ins# InputStreamReader.
+                              LineNumberingPushbackReader.)
+                     *out* (OutputStreamWriter. outs#)
+                     *err* (PrintWriter. outs# true)]
+             (clojure.main/repl ~@init-form))
+           (.close server#)))))
+
+(defn connect-to-repl [port]
+  (Thread/sleep 3000) ;; TODO: poll
+  (let [socket (Socket. "localhost" port)
+        reader (InputStreamReader. (.getInputStream socket))
+        writer (OutputStreamWriter. (.getOutputStream socket))
+        copy-out #(do (while (.ready reader)
+                         (Thread/sleep 100)
+                         (.write *out* (.read reader)))
+                       (flush))]
+    (loop []
+      (dotimes [_ 2] (copy-out))
+      (.write writer (str (pr-str (read)) "\n"))
+      (.flush writer)
+      (recur))))

 (defn repl [project]
-  (let [repl-init (and (:main project)
-                       [:init `#(doto '~(:main project) require in-ns)])]
-    (eval-in-project project
-                     `(clojure.main/repl ~@repl-init))))
+  (let [port (+ 1024 (rand-int 32000))]
+    (.start (Thread. #(eval-in-project project (repl-form project port))))
+    (connect-to-repl port)))


Remove a .getParent missed in 2d33bf6. Fixes :build-deps

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -174,7 +174,7 @@
 (defn find-project-files
   [^File d]
   (let [{:keys [lines]} (git {:gitdir d} "ls-files" "project.clj" "**/project.clj")]
-    (map #(str (.getParent d) "/" %) lines)))
+    (map #(str d "/" %) lines)))

 (defn contains-sha? [d sha]
   (->>


Avoid infinite loop on build-deps when lein fails

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -147,8 +147,12 @@

 (defn install-versioned-artifact
   [proot]
-  (let [r (sh "lein" "voom" "install" :dir proot)]
-    (prn "r" r)))
+  (let [install-cmd ["lein" "voom" "install" :dir proot]
+        _ (apply println "install-versioned-artifact:" install-cmd)
+        rtn (sh "lein" "voom" "install" :dir proot)]
+    (when-not (zero? (:exit rtn))
+      (throw (ex-info "lein voom install error" (assoc rtn :cmd install-cmd))))
+    rtn))

 (defn missing-artifacts-from-exception
   "Returns a sequence of artifacts indicated as missing anywhere in


CMR-4181: Updated preview gem to commit 2c39580.

--- collection-renderer-lib/project.clj
+++ collection-renderer-lib/project.clj
@@ -14,7 +14,7 @@
    the hardcoded commit id during dev integration with cmr_metadata_preview project.
    The hardcoded commit id should be updated when MMT releases a new version of the gem."
   (or (System/getenv "CMR_METADATA_PREVIEW_COMMIT")
-      "6983be7"))
+      "2c39580"))

 (def gem-install-path
   "The directory within this library where Ruby gems are installed."


CMR-6236: Updated Collection Preview Gems. (#897)

--- collection-renderer-lib/project.clj
+++ collection-renderer-lib/project.clj
@@ -12,7 +12,7 @@
   {:repo "https://git.earthdata.nasa.gov/scm/cmr/cmr_metadata_preview.git"
    :version "cmr_metadata_preview-0.2.0"
    :commit-id (or (System/getenv "CMR_METADATA_PREVIEW_COMMIT")
-                  "91cd5b93d51")})
+                  "92d73f5436210d1d56fcf769e6011d20d8959ebd")})

 (def gem-install-path
   "The directory within this library where Ruby gems are installed."


remove old todo, update watch-iref docstr

--- src/minreact/core.cljs
+++ src/minreact/core.cljs
@@ -49,7 +49,7 @@

 ;; NOTE om korks: Grepping large om codebases shows that in 99% of the
 ;; cases om/set-state! and om/update! are used with a single key
-;; --
+
 (defn set-state!
   "Set the components state to newval, at k if provided."
   ([c newval]
@@ -92,13 +92,6 @@
      (or (not= next-props props)
          (not= next-state state)))))

-;; TODO: One should be allowed to specifiy a getter that is watched
-;; explicitly as an optimization.  In the normal usecase this would be
-;; a keyword.  Keywords and ks vecs have equality, fns have not if
-;; they are lambdas, so users get better performance if they use
-;; keywords.  In this sense it would be great if vectors implemented
-;; get-in.
-
 (defn- install-watch [c [getter iref :as selector]]
   (let [k (gensym "minreact-watch__")]
     (state! c (fn [s]
@@ -133,6 +126,9 @@
   a vector [getter iref] where getter limits the observed part of
   iref.

+  Note that getter should be an equal value during each invocation of
+  render.
+
   Also refer to the with-irefs macro."
   [render-child selector]
   :state {:keys [value]}


Reduce length of temperature values to 1DP

--- app/pyrexia/src/pyrexia/colour_line.cljs
+++ app/pyrexia/src/pyrexia/colour_line.cljs
@@ -6,6 +6,9 @@

 (defn- mid [x y]
   (+ x (/ (- y x) 2)))
+
+(defn temp-format [val]
+    (gstring/format "%.1f" val))

 (defn- colours-view []
   (let [colour-count 20
@@ -17,9 +20,9 @@
     ^{:key :colour-map}
     [:svg {:width colour-width :height (* 2 bar-height)}
      (concat
-      [^{:key :beg-colour} [:text {:x 0 :y (- bar-height 2) :font-size bar-height} (:minValue @c/app-state)]
-       ^{:key :mid-colour} [:text {:x (- (/ colour-width 2) 40) :y (- bar-height 2) :font-size bar-height} (mid (:minValue @c/app-state) (:maxValue @c/app-state))]
-       ^{:key :end-colour} [:text {:x (- colour-width 40) :y (- bar-height 2) :font-size bar-height} (:maxValue @c/app-state)]]
+      [^{:key :beg-colour} [:text {:x 0 :y (- bar-height 2) :font-size bar-height} (temp-format (:minValue @c/app-state))]
+       ^{:key :mid-colour} [:text {:x (- (/ colour-width 2) 30) :y (- bar-height 2) :font-size bar-height} (temp-format (mid (:minValue @c/app-state) (:maxValue @c/app-state)))]
+       ^{:key :end-colour} [:text {:x (- colour-width 60) :y (- bar-height 2) :font-size bar-height} (temp-format (:maxValue @c/app-state))]]
       (map
        #(with-meta
           [:rect {:x (+ (* % box-width) 1)


make first attempt at section schema

make first attempt at section schema

--- src/oarlock/schema.clj
+++ src/oarlock/schema.clj
@@ -8,7 +8,6 @@
             [:id-sk-with-origin :string "Combined id-sk and id-sk-origin" :db.unique/identity]
             [:name :string]
             [:version :string] ; not null
-            ;; Example types: :project :course-competency ... TODO: enum?
             [:type :string] ; not null
             [:duration-rating-days :bigint]
             [:comps :ref :many]
@@ -23,16 +22,24 @@
             [:name :string]
             [:version :string]
             [:description :string]
-            ;; TODO: is this correct?
             [:comps :ref :many]]
     :dbfns [(constraints/unique :perf-asmt :id-sk :id-sk-origin)]}
+   {:namespace :section
+    :attrs [[:id-sk :string]
+            [:instructor :ref]
+            [:perf-asmts :ref :many]
+            [:status :enum [:active :archived :preactive]]]}
    {:namespace :user2perf-asmt
     :attrs [[:user :ref]
             [:perf-asmt :ref]
-            ;; TODO: finish this
             [:grade :boolean]]}
    {:namespace :user2task
     :attrs [[:user :ref]
             [:task :ref]
-            ;; TODO: finish this
-            [:progress :boolean]]}])
+            [:progress :boolean]]}
+   {:namespace :user2section
+    :attrs [[:user :ref]
+            [:section :ref]
+            ;; TODO: do we want to use our current model of status, or do something different?
+            [:status :enum [:active :completed :withdrawn-failing :withdrawn-no-grade]]
+            [:activation-status :enum [:assigned :assigned-emailed :enabled :contact-instructor]]]}])


Fix bug

Fix bug

--- src/obb_rules/unit.clj
+++ src/obb_rules/unit.clj
@@ -1,4 +1,6 @@
-(ns obb-rules.unit)
+(ns obb-rules.unit
+  (:require [obb-rules.units.rain]
+            [obb-rules.units.crusader]))

 (defn get-units
   "Gets all the available units"


More package output enhancements

More package output enhancements

Signed-off-by: Gregory Haskins <640d9fe47775e6723f0355b7315e38f7d98d3539@gmail.com>

--- src/obcc/dar/write.clj
+++ src/obcc/dar/write.clj
@@ -112,4 +112,5 @@

   (println div)
   (println "Digital Signature: none")
+  (println "Final Size:       " (.length outputfile) "bytes")
   (println "Chaincode Hash:    n/a"))


Fix panel ignoring content elements beyond the first 2.

--- src/om_forms/core.cljs
+++ src/om_forms/core.cljs
@@ -139,8 +139,8 @@

 (defn parse-options
   [args]
-  (let [[options [rest-args]] (split-with (comp keyword? first) (partition-all 2 args))]
-    [(apply hash-map (mapcat identity options)) (or rest-args [])]))
+  (let [[options rest-args] (split-with (comp keyword? first) (partition-all 2 args))]
+    [(apply hash-map (mapcat identity options)) (mapcat identity (or rest-args []))]))

 (defn input*
   [tag attrs label cursor korks {:keys [valid? validation-error-fn in-progress warn-fn help inline large]} & inner]
@@ -199,7 +199,7 @@

   [& args]
   (let [[attrs [title & rest-args]] (resolve-args :panel {:class "panel panel-default"} args)
-        [{:keys [close]} [& contents]] (parse-options rest-args)]
+        [{:keys [close]} & contents] (parse-options rest-args)]
     [:div attrs
      [:div {:class "panel-heading"}
       [:h3 {:class "panel-title"} title]
@@ -464,7 +464,6 @@
   (f/textarea {:rows 8} \"Textarea\" \"A placeholder\" data [:some-text] :inline true)"

   [& args]
-  (js/console.log (prn-str args))
   (let [[attrs [label placeholder cursor korks & opts]] (resolve-args :textarea {:class "form-control"} args)
         dom-id (gen-dom-id cursor korks)
         textarea-attrs (merge-attrs {:class       "form-control"


better chrome

better chrome

--- src/prais2/chrome.cljs
+++ src/prais2/chrome.cljs
@@ -54,7 +54,7 @@

 (rum/defc bs-fixed-navbar  [active-key]
   (let [nav-item (active-key nav-items)]
-    [:nav.navbar.navbar-fixed-top.navbar-inverse
+    [:nav.navbar.navbar-default.navbar-fixed-top {:margin-bottom 0}
      [:.container
       [:.navbar-header {:key 1}
        [:button.navbar-toggle.collapsed {:key 1
@@ -82,41 +82,46 @@

 (rum/defc header < rum/reactive [& deep]
   [:div
-   {:style
-    {:width "100%"
-     :height (if deep "235px" "80px")
-     :background-color "#475E63"
-     :color "rgba(255,255,255,0.5)"
-     :position "relative"
-     }}
-   (when deep
-     [:div {:style
-            {:position "absolute"
-             :z-index 1;
-             :left "12px"
-             :top "60px"
-             :background-image "url(assets/logo-placeholder.png)"
-             :background-repeat "no-repeat"
-             :background-size "100%"
-             :width "150px"
-             :height "135px"
-             :border "none"
-             :color "white"
-             :text-align "center"
-             :padding-top "24px"
-             :font-size "1.5em"}}])
    (bs-fixed-navbar (:page (rum/react core/app)))
-   (when deep
-     [:h1 {:style
-           {:color "#CCDDFF"
-            :position "relative"
-            :font-size "2em"
-            :top "0px"
-            :right "25px"
-            :text-align "right"
-            :padding-left "160px"
-            :z-index 100
-            }} "UNDERSTANDING PUBLISHED CHILDREN’S HEART SURGERY OUTCOMES"])])
+   [:div
+    {:style
+     {:width "100%"
+      :height (if deep "170px" "80px")
+      :background-color "#475E63"
+      :color "rgba(255,255,255,0.5)"
+      :position "relative"
+      }}
+    (when deep
+      [:div
+       [:div {:style
+              {:position "relative"
+               :z-index 1;
+               :left "12px"
+               :top "20px"
+               :background-image "url(assets/logo-placeholder.png)"
+               :background-repeat "no-repeat"
+               :background-size "100%"
+               :width "150px"
+               :height "135px"
+               :border "none"
+               :color "white"
+               :text-align "right"
+               :float "left"
+               :padding-top "24px"}}
+
+        ]
+       [:h3 {:style
+             {:float "right"
+              :clear "none"
+              :color "#CCDDFF"
+              :width "calc(100% - 160px)"
+              :position "relative"
+              :top "0px"
+              :right "25px"
+              :text-align "right"
+              :z-index 100
+              }} "UNDERSTANDING PUBLISHED CHILDREN’S HEART SURGERY OUTCOMES"]])
+    ]])


logger reading from google -- not quite

logger reading from google -- not quite

--- src/prais2/logger.cljs
+++ src/prais2/logger.cljs
@@ -50,7 +50,8 @@
 (get-ip-address)

-(def store-session-app "https://script.google.com/a/macros/cam.ac.uk/s/AKfycbx1wfGXBMVImgmiyOY9JvcnV5tBNS8YyAlIiv73q4gjvkbRiis/exec")
+(def store-session-app "https://script.google.com/macros/s/AKfycbx1wfGXBMVImgmiyOY9JvcnV5tBNS8YyAlIiv73q4gjvkbRiis/exec"
+  )

 (def sheets-logger-app "https://script.google.com/a/macros/cam.ac.uk/s/AKfycbwg81jLTtCY_cU3qOVv6A93GePfnpAj-HxBM_7_nF8B-DkfyLp5/exec")

@@ -61,20 +62,22 @@
   [response]
   (.log js/console (str response)))

-(defn sheets-error-handler
+(defn sheets-write-error
   [status status-text]
   (.log js/console (str "spreadsheet write error " status " " status-text)))

+(defn sheets-read-error
+  [status status-text]
+  (.log js/console (str "spreadsheet read error " status " " status-text)))
+
 (defn save-session
   "Write out a session to the store."
   []
-  (prn "saving")
-  (prn (sit/write log-w @log-state))
   (POST store-session-app
         :params (str "ip=" @ip-address
                      "&saved-session=" (sit/write log-w @log-state))
         :handler sheets-success-handler
-        :error-handler sheets-error-handler
+        :error-handler sheets-write-error
         :format {:write identity
                  :content-type "application/x-www-form-urlencoded"}
         :response-format :json
@@ -82,7 +85,12 @@

 (defn load-session
   []
-  (prn "load-session not yet implemented"))
+  (prn "load-session not yet implemented")
+  (GET store-session-app
+       :handler sheets-success-handler
+       :error-handler sheets-read-error
+       :response-format :json
+       :keywords? true))

 (defn write-sheet-log
   "Write a log-event to the google sheet url."
@@ -105,7 +113,7 @@
                        "&map-selection=" (:map-h-code app-state)
                        )
           :handler sheets-success-handler
-          :error-handler sheets-error-handler
+          :error-handler sheets-write-error
           :format {:write identity
                    :content-type "application/x-www-form-urlencoded"}
           :response-format :json
@@ -129,7 +137,7 @@
     ;;                            "&map-selection=" (:map-h-code app-state)
     ;;                            )
     ;;               :handler sheets-success-handler
-    ;;               :error-handler sheets-error-handler
+    ;;               :error-handler sheets-write-error
     ;;               :format {:write identity
     ;;                        :content-type "application/x-www-form-urlencoded"}
     ;;               :response-format (json-response-format {:keywords? true})


default-factory fn has been added to webserver component

--- src/clj/hellhound/components/webserver.clj
+++ src/clj/hellhound/components/webserver.clj
@@ -7,12 +7,13 @@
   returns a component map."
   ^{:author "Sameer Rahmani (@lxsameer)"}
   (:require
-   [clojure.spec.alpha :as s]
-   [aleph.http         :as http]
-   [hellhound.logger   :as log]
-   [hellhound.spec     :as spec]
-   [hellhound.core     :as hellhound]
+   [clojure.spec.alpha  :as s]
+   [aleph.http          :as http]
+   [hellhound.logger    :as log]
+   [hellhound.spec      :as spec]
+   [hellhound.core      :as hellhound]
    [hellhound.component :as hcomp]
+   [hellhound.http      :as http]
    [hellhound.http.route :as router]))

 ;; TODO: Extract the spec check into a predicate function called map-with
@@ -80,3 +81,15 @@
      {:hellhound.component/name ::webserver
       :hellhound.component/start-fn (start! routes web-hooks config)
       :hellhound.component/stop-fn stop!})))
+
+(defn default-factory
+  "Returns a new webserver component which uses the default routes and
+  configuration of *HellHound*.
+
+  TODO: more docs"
+  ([]
+   (factory http/default-routes))
+
+  ([hooks]
+   (factory http/default-routes
+            (merge default-hooks hooks))))


Renamed old-db to db

Renamed old-db to db

--- src/cljs/wombats_web_client/events/ui.cljs
+++ src/cljs/wombats_web_client/events/ui.cljs
@@ -1,7 +1,7 @@
 (ns wombats-web-client.events.ui
   (:require [re-frame.core :as re-frame]
             [cemerick.url :as url]
-            [wombats-web-client.db :as db]
+            [wombats-web-client.db :refer [default-db]]
             [wombats-web-client.utils.url :refer [strip-access-token]]
             [wombats-web-client.utils.local-storage :refer [set-token! get-token]]
             [wombats-web-client.constants.local-storage :refer [access-token]]
@@ -9,8 +9,8 @@

 (re-frame/reg-event-db
  :initialize-db
- (fn [old-db _]
-   (merge db/default-db old-db)))
+ (fn [db _]
+   (merge default-db db)))

 (re-frame/reg-event-db
  :bootstrap-app


Commented out testing code

Commented out testing code

--- src/clojush/problems/software/checksum.clj
+++ src/clojush/problems/software/checksum.clj
@@ -192,46 +192,53 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;

-(reset! global-evalpush-limit 1500)
-
-(reset! global-max-points 800)
-
-(defn test-program-on-training
-  [program]
-  ((checksum-error-function checksum-data-domains) program))
-
-(defn run-prog
-  [program print-steps]
-  (let [input "dl2HKsdJ2 jad2E\"d2n\nad3!"
-        final-state (run-push program
-                              (->> (make-push-state)
-                                (push-item input :input)
-                                (push-item "" :output))
-                              print-steps)
-        printed-result (stack-ref :output 0 final-state)]
-    (doseq [[nm stack] (sort-by #(name (first %)) final-state)]
-      (println (format "%-12s | %s" nm (pr-str stack))))))
-
-;(char (+ (mod (apply + (map int "qwerty")) 64)
-;         (int \space)))
-
-(char (+ (int \space) (mod (apply + (map int "")) 64)))
-
-(def tom-program
-  '(
-     "Check sum is " print_string
-     in1 char_allfromstring
-     100 exec_do*times
-     (integer_fromchar integer_add 5.2 4.5 float_add float_add)
-     64 integer_swap 64 integer_mod
-     \space integer_fromchar integer_add
-     char_frominteger
-     print_char
-     ))
+;(reset! global-evalpush-limit 1500)
+;
+;(reset! global-max-points 800)
+;
+;(defn test-program-on-training
+;  [program]
+;  ((checksum-error-function checksum-data-domains) program))
+;
+;(defn run-prog
+;  [program print-steps]
+;  (let [input "dl2HKsdJ2 jad2E\"d2n\nad3!"
+;        final-state (run-push program
+;                              (->> (make-push-state)
+;                                (push-item input :input)
+;                                (push-item "" :output))
+;                              print-steps)
+;        printed-result (stack-ref :output 0 final-state)]
+;    (doseq [[nm stack] (sort-by #(name (first %)) final-state)]
+;      (println (format "%-12s | %s" nm (pr-str stack))))))
+;
+;(def tom-program
+;  '(
+;     "Check sum is " print_string
+;     in1 char_allfromstring
+;     100 exec_do*times
+;     (integer_fromchar integer_add)
+;     64 integer_swap 64 integer_mod
+;     \space integer_fromchar integer_add
+;     char_frominteger
+;     print_char
+;     ))
+;
+;(def while-program
+;  '(
+;     "Check sum is " print_string
+;     in1 char_allfromstring
+;     exec_do*while
+;     (integer_fromchar integer_add char_empty boolean_not)
+;     64 integer_swap 64 integer_mod
+;     \space integer_fromchar integer_add
+;     char_frominteger
+;     print_char
+;     ))

 ;(test-program-on-training tom-program)

 ;(run-prog tom-program false)

-
+;(test-program-on-training while-program)


Removing println.

Removing println.

--- src/cmr/indexer/services/index_service.clj
+++ src/cmr/indexer/services/index_service.clj
@@ -86,5 +86,3 @@
   (cache/reset-cache (-> context :system :cache))
   (acl-cache/reset context))

-
-


Add getter / setter for supportive?

Add getter / setter for supportive?

--- src/discuss/references/lib.cljs
+++ src/discuss/references/lib.cljs
@@ -21,6 +21,13 @@
   []
   (get-in @lib/app-state [:reference-usages :selected-statement]))

+(defn supportive?
+  "Store if a user supports the statement or not."
+  ([]
+    (get-in @lib/app-state [:reference-usages :supportive?]))
+  ([bool]
+   (lib/update-state-item! :reference-usages :supportive? (fn [_] bool))))
+
 (defn get-reference-usages
   "Return list of reference usages, which were previously stored in the app-state.
    TODO: optimize"


Added slightly improved error messages for attempting to use appengine-app-id and appengine-app-version with the server turned off.

--- src/appengine_magic/core.clj
+++ src/appengine_magic/core.clj
@@ -25,11 +25,17 @@

 (defn appengine-app-id []
-  (-> (ApiProxy/getCurrentEnvironment) .getAppId))
+  (try
+    (-> (ApiProxy/getCurrentEnvironment) .getAppId)
+    (catch NullPointerException npe
+      (throw (RuntimeException. "the server must be running" npe)))))

 (defn appengine-app-version []
-  (-> (ApiProxy/getCurrentEnvironment) .getVersionId))
+  (try
+    (-> (ApiProxy/getCurrentEnvironment) .getVersionId)
+    (catch NullPointerException npe
+      (throw (RuntimeException. "the server must be running" npe)))))

 (if (in-appengine-interactive-mode?)


Use /tmp/copaste-store.git for the data store

--- src/server/systems.clj
+++ src/server/systems.clj
@@ -8,9 +8,9 @@
 (defsystem development-system
   [:app-server (new-web-server 3000 app-server)
    :backend-server (new-web-server 3001 backend-server)
-   :consonant (new-local-store "/home/jannis/tmp/copaste-store.git")])
+   :consonant (new-local-store "/tmp/copaste-store.git")])

 (defsystem production-system
   [:app-server (new-web-server 3000 app-server)
    :backend-server (new-web-server 3001 backend-server)
-   :consonant (new-local-store "/home/jannis/tmp/copaste-store.git")])
+   :consonant (new-local-store "/tmp/copaste-store.git")])


separate tick rules, better syntax

separate tick rules, better syntax

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- src/aurora/runtime/core.cljs
+++ src/aurora/runtime/core.cljs
@@ -18,12 +18,12 @@
   (datalog/chain (for [stratum strata]
                    (datalog/fixpoint (datalog/chain stratum)))))

-(defn tick [kn rules watchers feeder-fn]
-  (println "ticking: " watchers)
-  (let [chained (chain-rules rules)
+(defn tick [kn tick-rules rules watchers feeder-fn]
+  (let [chained-tick-rules (datalog/chain tick-rules)
+        kn (chained-tick-rules kn)
+        chained (chain-rules rules)
         kn (chained kn)]
     (doseq [watch watchers]
-      (println "going through watchers")
       (watch kn feeder-fn))
     (datalog/and-now kn)))

@@ -38,7 +38,7 @@
                (-> cur
                    (datalog/assert-many feed-set)
                    (datalog/and-now)
-                   (tick (:rules @env) (:watchers @env) (:feeder-fn @env))
+                   (tick (:tick-rules @env) (:rules @env) (:watchers @env) (:feeder-fn @env))
                    (datalog/retract-many feed-set)
                    (datalog/and-now))))
       (.timeEnd js/console "run")
@@ -51,15 +51,19 @@
     (handle-feed env)
     env))

-(defn make-env
-  ([kn rules]
-   (make-env kn rules @watchers))
-  ([kn rules watchers]
-   (atom {:kn (datalog/Knowledge. kn #{} #{})
-          :rules rules
-          :watchers watchers
-          :feed (array)
-          :queued? false})))
+(defn ->env [opts]
+  (atom (merge {:tick-rules []
+                :rules []
+                :watchers @watchers
+                :feed (array)
+                :queued? false}
+               opts
+               {:kn (datalog/Knowledge. (:kn opts #{}) #{} #{})})))
+
+(defn run-env [opts]
+  (-> opts
+      (->env)
+      (run)))

 (defn pause [env]
   (swap! env assoc :paused true))
@@ -73,139 +77,100 @@

 (def hiccup js/aurora.runtime.ui.hiccup->facts)

-  (def tick (-> (make-env #{[3 5] [9 8 7] [:tick]}
-                          [
-                           ;;clean up rules
-                           [(rule {:name :wait :time t :id i}
-                                  (- {:name :wait :time t :id i}))]
-                           ;;program rules
-                           [(rule [:tick]
+  (def tick (run-env {:kn #{[3 5] [9 8 7] [:tick]}
+                      :tick-rules [(rule {:name :wait :time t :id i}
+                                         (- {:name :wait :time t :id i}))]
+                      :rules [(rule [:tick]
                                   (- [:tick])
                                   (+ {:name :wait :time 1000 :id 1}))
-                            (rule {:name :tick :id 1 :timestamp ts}
+                              (rule {:name :tick :id 1 :timestamp ts}
                                   (+ [:tick])
-                                  (+ ["hi!" ts]))
-                            ]])
-                (run)))
+                                  (+ ["hi!" ts]))]}))

   (pause tick)
   (unpause tick)
   @tick

-  (def clock (-> (make-env #{[:tick]}
-                           [
-                            ;;clean up rules
-                            [(rule {:name :wait :time t :id i}
-                                   (- {:name :wait :time t :id i}))
-                             (rule {:name :ui/text :id "time-0" :text text}
-                                   (- {:name :ui/text :id "time-0" :text text}))]
-                            ;;program rules
-                            [(rule [:tick]
-                                   (- [:tick])
-                                   (+ {:name :wait :time 1000 :id "clock"}))
-                             (rule {:name :tick :id "clock" :timestamp ts}
-                                   (+ {:name :wait :time 1000 :id "clock"})
-                                   (+s (hiccup [:p {:id "time"} (str "time is: " (js/Date. ts))]))
-                                   )
-                             ]])
-                 (run)))
+  (def clock (run-env {:kn #{{:name :tick :id "clock" :timestamp ""}}
+                       :tick-rules [(rule {:name :wait :time t :id i}
+                                          (- {:name :wait :time t :id i}))
+                                    (rule {:name :ui/text :id "time-0" :text text}
+                                          (- {:name :ui/text :id "time-0" :text text}))
+                                    (rule {:name :tick :id "clock" :timestamp ts}
+                                          (+ {:name :wait :time 1000 :id "clock"}))
+                                    ]
+                       :rules [[(rule {:name :tick :id "clock" :timestamp ts}
+                                      (+s (hiccup [:p {:id "time"} (str "time is: " (js/Date. ts))])))
+                                ]]
+                       }))

   (pause clock)
   (unpause clock)
   @clock

-  (def incrementer (-> (make-env #{{:name "counter" :value 0}}
-                                 [;;clean up rules
-                                  [(rule {:name :ui/text :id "counter-ui-0" :text text}
-                                         (- {:name :ui/text :id "counter-ui-0" :text text}))]
-                                  ;;program rules
-                                  [(rule {:name :ui/onClick :id "incr-button"}
-                                         {:name "counter" :value v}
-                                         (- {:name :ui/onClick :id "incr-button"})
-                                         (- {:name "counter" :value v})
-                                         (+ {:name "counter" :value (inc v)}))]
-                                  [(rule {:name "counter" :value v}
-                                         (+s (hiccup
-                                              [:p {:id "counter-ui"} v]
-                                              [:button {:id "incr-button" :events ["onClick"]} "increment"])))]])
-                       (run)))
+  (def incrementer (run-env {:kn #{{:name "counter" :value 0}}
+                             :tick-rules [(rule {:name :ui/text :id "counter-ui-0" :text text}
+                                                (- {:name :ui/text :id "counter-ui-0" :text text}))
+                                          (rule {:name :ui/onClick :id "incr-button"}
+                                                {:name "counter" :value v}
+                                                (- {:name "counter" :value v})
+                                                (+ {:name "counter" :value (inc v)}))]
+                             :rules [[(rule {:name "counter" :value v}
+                                            (+s (hiccup
+                                                 [:p {:id "counter-ui"} v]
+                                                 [:button {:id "incr-button" :events ["onClick"]} "increment"])))]]}))

   (pause incrementer)
   (unpause incrementer)
   (:kn @incrementer)

-
-  (def +s-test (-> (make-env #{[:tick] [:whee] [:zomg]}
-                             [
-                              ;;clean up rules
-                              [(rule {:name :ui/text :id "counter-value" :text text}
-                                     (- {:name :ui/text :id "counter-value" :text text}))
-                               ]
-                              ;;program rules
-                              [(rule [:tick]
-                                     (-s (map vector [:tick :zomg]))
-                                     (+s [{:name "foo"} {:name "zomg"}])
-                                     )
-                               ]])
-                   (run)))
-
-  (def fetcher (-> (make-env #{{:name "content" :value "Click button to fetch google"}}
-                             [;;clean up rules
-                              [
-                               (rule {:name :ui/text :id "content-ui-0" :text text}
-                                     (- {:name :ui/text :id "content-ui-0" :text text}))
-                               (rule {:name :http-get :url "http://tycho.usno.navy.mil/cgi-bin/timer.pl" :id "google"}
-                                     (- {:name :http-get :url "http://tycho.usno.navy.mil/cgi-bin/timer.pl" :id "google"}))]
-                              ;;program rules
-                              [(rule {:name :ui/onClick :id "fetch-button"}
-                                     (+ {:name :http-get :url "http://tycho.usno.navy.mil/cgi-bin/timer.pl" :id "google"}))
-                               (rule {:name :http-response :id "google" :data data}
-                                     {:name "content" :value v}
-                                     (- {:name "content" :value v})
-                                     )
-                               ]
-                              [(rule {:name :http-response :id "google" :data data}
-                                     (+ {:name "content" :value data})
-                                     )]
-                              [(rule {:name "content" :value v}
-                                     (+s (hiccup
-                                          [:p {:id "content-ui"} v]
-                                          [:button {:id "fetch-button" :events ["onClick"]} "fetch"])))]])
-                   (run)))
+  (def fetcher (run-env {:kn #{{:name "content" :value "Click button to fetch google"}}
+                         :tick-rules [(rule {:name :ui/text :id "content-ui-0" :text text}
+                                             (- {:name :ui/text :id "content-ui-0" :text text}))
+                                       (rule {:name :http-get :url "https://google.com" :id "google"}
+                                             (- {:name :http-get :url "https://google.com" :id "google"}))
+                                       (rule {:name :ui/onClick :id "fetch-button"}
+                                             (+ {:name :http-get :url "https://google.com" :id "google"}))
+                                       (rule {:name :http-response :id "google" :data data}
+                                             {:name "content" :value v}
+                                             (- {:name "content" :value v})
+                                             (+ {:name "content" :value data}))
+                                       ]
+                         :rules [[(rule {:name "content" :value v}
+                                        (+s (hiccup
+                                             [:p {:id "content-ui"} v]
+                                             [:button {:id "fetch-button" :events ["onClick"]} "fetch"])))]]}))

   (-> @fetcher :kn :old)

-  (def todo (-> (make-env #{{:name "counter" :value 2}
+  (def todo (run-env {:kn #{{:name "counter" :value 2}
                             {:name "todo" :id 0 :text "get milk" :order 0}
                             {:name "todo" :id 1 :text "take books back" :order 1}
                             {:name "todo" :id 2 :text "cook" :order 2}
                             }
-                          [;;clean up rules
-                           []
-                           ;;program rules
-                           [(rule {:name :ui/onClick :id "add-todo"}
-                                  {:name "counter" :value v}
-                                  (- {:name :ui/onClick :id "add-todo"})
-                                  (- {:name "counter" :value v})
-                                  (+ {:name "counter" :value (inc v)})
-                                  (+ {:name "todo" :id (inc v) :text (str "new todo " (+ 2 v)) :order (inc v)})
-                                  )]
-                           [(rule {:name "todo" :id id :text text :order order}
-                                  (+s (hiccup
-                                       [:li {:id (str "todo" id)} text]))
-                                  (+ {:name :ui/child :id "todo-list" :child (str "todo" id) :pos order}))]
-                           [(rule (+s (hiccup
-                                       [:div {:id "app"}
-                                        [:h1 {:id "todo-header"} "Todos"]
-                                        [:input {:id "todo-input" :placeholder "What do you need to do?"}]
-                                        [:button {:id "add-todo" :events ["onClick"]} "add"]
-                                        [:ul {:id "todo-list"}]
-                                        ]))
-                                  )]
-                           ])
-                (run)))
+                      :tick-rules [
+                                   (rule {:name :ui/onClick :id "add-todo"}
+                                         {:name "counter" :value v}
+                                         (- {:name "counter" :value v})
+                                         (+ {:name "counter" :value (inc v)})
+                                         (+ {:name "todo" :id (inc v) :text (str "new todo " (+ 2 v)) :order (inc v)}))
+
+                                   ]
+                      :rules [[(rule {:name "todo" :id id :text text :order order}
+                                     (+s (hiccup
+                                          [:li {:id (str "todo" id)} text]))
+                                     (+ {:name :ui/child :id "todo-list" :child (str "todo" id) :pos order}))]
+                              [(rule (+s (hiccup
+                                          [:div {:id "app"}
+                                           [:h1 {:id "todo-header"} "Todos"]
+                                           [:input {:id "todo-input" :placeholder "What do you need to do?"}]
+                                           [:button {:id "add-todo" :events ["onClick"]} "add"]
+                                           [:ul {:id "todo-list"}]
+                                           ]))
+                                     )]
+                              ]}))

   )


Seperate out todo-env

Seperate out todo-env

--- src/aurora/runtime/core.cljs
+++ src/aurora/runtime/core.cljs
@@ -117,22 +117,22 @@

 (defn go-to-do []

-(def hiccup js/aurora.runtime.ui.hiccup->facts)
-(def ui-cleanup-rules [(rule ^d {:ml :ui/text}
-                             (- d))
-                       (rule ^d {:ml :ui/elem}
-                             (- d))
-                       (rule ^d {:ml :ui/attr}
-                             (- d))
-                       (rule ^d {:ml :ui/style}
-                             (- d))
-                       (rule ^d {:ml :ui/child}
-                             (- d))
-                       (rule ^d {:ml :ui/event-listener}
-                             (- d))
-                       (rule ^d {:ml :ui/draw}
-                             (- d))
-                       ])
+  (def hiccup js/aurora.runtime.ui.hiccup->facts)
+  (def ui-cleanup-rules [(rule ^d {:ml :ui/text}
+                               (- d))
+                         (rule ^d {:ml :ui/elem}
+                               (- d))
+                         (rule ^d {:ml :ui/attr}
+                               (- d))
+                         (rule ^d {:ml :ui/style}
+                               (- d))
+                         (rule ^d {:ml :ui/child}
+                               (- d))
+                         (rule ^d {:ml :ui/event-listener}
+                               (- d))
+                         (rule ^d {:ml :ui/draw}
+                               (- d))
+                         ])

   (def timer-cleanup-rules [(rule ^t {:ml :timers/wait}
                                   (- t))])
@@ -140,178 +140,180 @@
   (def io-cleanup-rules [(rule ^get {:name :http-get}
                                (- get))])

-  (def todo (run-env {:kn #{{:name "counter" :value 2}
-                            {:name "todo" :id 0 :text "get milk" :order 0}
-                            {:name "todo" :id 1 :text "take books back" :order 1}
-                            {:name "todo" :id 2 :text "cook" :order 2}
-                            {:name "todo-done" :id 0 :done? "false"}
-                            {:name "todo-done" :id 1 :done? "false"}
-                            {:name "todo-done" :id 2 :done? "false"}
-                            {:name "todo-editing" :id 0 :editing? "false"}
-                            {:name "todo-editing" :id 1 :editing? "false"}
-                            {:name "todo-editing" :id 2 :editing? "false"}
-                            {:name :todo/current-text :value ""}
-                            {:name :todo/filter :value "all"}
-                            {:name :todo/toggle-all :value "false"}
-                            }
-                      :cleanup-rules (concat ui-cleanup-rules
-                                             [(rule ^disp {:name :todo/displayed}
-                                                    (- disp))])
-                      :tick-rules [;;on change
-                                   (rule {:name :ui/onChange :id "todo-input" :value v}
-                                         (> {:name :todo/current-text} {:value v}))
-
-                                   ;;submit
-                                   (rule {:name :ui/onClick :id "add-todo"}
-                                         (+ {:name :todo/new!}))
-                                   (rule {:name :ui/onKeyDown :id "todo-input" :keyCode 13}
-                                         (+ {:name :todo/new!}))
-
-                                   ;;add a new todo
-                                   (rule {:name :todo/new!}
-                                         {:name "counter" :value v}
-                                         {:name :todo/current-text :value text}
-                                         (= new-count [v] (inc v))
-                                         (- {:name :todo/new!})
-                                         (> {:name "counter"} {:value new-count})
-                                         (> {:name :todo/current-text} {:value ""})
-                                         (+ {:name "todo" :id new-count :text text :order new-count})
-                                         (+ {:name "todo-editing" :id new-count :editing? "false"})
-                                         (+ {:name "todo-done" :id new-count :done? "false"}))
-
-                                   ;;todo editing
-                                   (rule {:name :ui/onDoubleClick :entity ent}
-                                         {:name "todo-editing" :id ent :editing? "false"}
-                                         (> {:name "todo-editing" :id ent} {:editing? "true"}))
-
-                                   (rule {:name :ui/onBlur :entity ent}
-                                         {:name :todo/edit-text :value v}
-                                         (> {:name "todo" :id ent} {:text v})
-                                         (> {:name "todo-editing" :id ent} {:editing? "false"}))
-
-                                   (rule {:name :ui/onChange :id "todo-editor" :value v}
-                                         (> {:name :todo/edit-text} {:value v})
-                                         (+ {:name :todo/edit-text :value v}))
-
-                                   (rule {:name :ui/onKeyDown :id "todo-editor" :keyCode 13 :entity ent}
-                                         {:name :todo/edit-text :value new-value}
-                                         (> {:name "todo" :id ent} {:text new-value})
-                                         (> {:name "todo-editing" :id ent} {:editing? "false"}))
-
-                                   (rule {:name :ui/onChange :event-key "todo-checkbox" :entity ent :value v}
-                                         (> {:name "todo-done" :id ent} {:done? v}))
-
-                                   (rule {:name :ui/onClick :event-key "filter-all"}
-                                         (> {:name :todo/filter} {:value "all"}))
-                                   (rule {:name :ui/onClick :event-key "filter-active"}
-                                         (> {:name :todo/filter} {:value "false"}))
-                                   (rule {:name :ui/onClick :event-key "filter-completed"}
-                                         (> {:name :todo/filter} {:value "true"}))
-
-                                   (rule {:name :ui/onChange :event-key "toggle-all" :value v}
-                                         (> {:name :todo/toggle-all} {:value v}))
-
-                                   (rule {:name "todo-done" :id id}
-                                         {:name :ui/onChange :event-key "toggle-all" :value v}
-                                         (> {:name "todo-done" :id id} {:done? v}))
-
-                                   (rule {:name :ui/onClick :event-key "clear completed"}
-                                         {:name "todo-done" :id ent :done? "true"}
-                                         (+ {:name :todo/remove! :id ent}))
-
-                                   (rule {:name :ui/onClick :event-key "todo-remove" :entity ent}
-                                         (+ {:name :todo/remove! :id ent}))
-
-                                   (rule {:name :todo/remove! :id id}
-                                         ^todo {:name "todo" :id id}
-                                         ^done {:name "todo-done" :id id}
-                                         ^editing {:name "todo-editing" :id id}
-                                         (- todo)
-                                         (- done)
-                                         (- editing))]
-
-                      :rules [(rule {:name "todo" :id id}
-                                    {:name :todo/filter :value "all"}
-                                    (+ {:name :todo/displayed :id id}))
-                              (rule {:name "todo" :id id}
-                                    {:name :todo/filter :value v}
-                                    {:name "todo-done" :id id :done? v}
-                                    (+ {:name :todo/displayed :id id}))
-
-                              (rule {:name :todo/displayed :id id}
-                                    {:name "todo" :id id :text text :order order}
-                                    {:name "todo-done" :id id :done? done}
-                                    (= parent-id [id] (str "todo" id))
-                                    (= child-id [id] (str "todo-checkbox" id))
-                                    (+s [child-id id done]
-                                        (hiccup
-                                         [:input {:id child-id
-                                                  :event-key "todo-checkbox"
-                                                  :entity id
-                                                  :checked done
-                                                  :events ["onChange"]
-                                                  :type "checkbox"}]))
-                                    (+ {:name :ui/child :id parent-id :child child-id :pos -1}))
-                              (rule {:name :todo/displayed :id id}
-                                    {:name "todo" :id id :text text :order order}
-                                    {:name "todo-editing" :id id :editing? "false"}
-                                    (+s [id text]
-                                        (hiccup
-                                         [:li {:id (str "todo" id) :entity id :event-key "todo" :events ["onDoubleClick"]}
-                                          text
-                                          [:button {:id (str "todo-remove" id) :style {:margin-left "10px"} :entity id :event-key "todo-remove" :events ["onClick"]} "x"]]))
-                                    (= child-id [id] (str "todo" id))
-                                    (+ {:name :ui/child :id "todo-list" :child child-id :pos order}))
-                              (rule {:name :todo/displayed :id id}
-                                    {:name "todo" :id id :text text :order order}
-                                    {:name "todo-editing" :id id :editing? "true"}
-                                    (+s [id text]
-                                        (hiccup
-                                         [:input {:id (str "todo-editor") :entity id :event-key "todo-editor" :defaultValue text :events ["onChange" "onKeyDown" "onBlur"]}]))
-                                    (+ {:name :ui/child :id "todo-list" :child "todo-editor" :pos order}))
-
-                              (rule {:name :todo/current-text :value v}
-                                    (+s []
-                                        (hiccup
-                                         [:input {:id "todo-input" :value v :event-key "todo-input" :events ["onChange" "onKeyDown"] :placeholder "What do you need to do?"}]))
-                                    (+ {:name :ui/child :id "app" :child "todo-input" :pos 1}))
-
-                              (rule (set remaining [id]
-                                         {:name "todo-done" :id id :done? "false"})
-                                    (= left [remaining] (count remaining))
-                                    (= text [left] (if (= left 1)
-                                                     " todo "
-                                                     " todos "))
-                                    (+s [left text]
-                                        (hiccup [:span {:id "remaining-count"} left text "left"]))
-                                    (+ {:name :ui/child :id "app" :child "remaining-count" :pos 3.5}))
-
-                              (rule (set completed [id]
-                                         {:name "todo-done" :id id :done? "true"})
-                                    (= left [completed] (count completed))
-                                    (? [left] (> left 0))
-                                    (+s [left]
-                                        (hiccup [:span {:id "completed-count" :event-key "clear completed" :events ["onClick"]} "clear completed (" left ")"]))
-                                    (+ {:name :ui/child :id "app" :child "completed-count" :pos 7}))
-
-                              (rule {:name :todo/toggle-all :value toggle}
-                                    (+s [toggle]
-                                        (hiccup
-                                         [:div {:id "app"}
-                                          [:h1 {:id "todo-header"} "Todos"]
-                                          [:input {:id "toggle-all"
-                                                   :event-key "toggle-all"
-                                                   :checked toggle
-                                                   :events ["onChange"]
-                                                   :type "checkbox"}]
-                                          [:button {:id "add-todo" :event-key "add-todo" :events ["onClick"]} "add"]
-                                          [:ul {:id "todo-list"}]
-                                          [:button {:id "filter-all" :event-key "filter-all" :events ["onClick"]} "all"]
-                                          [:button {:id "filter-active" :event-key "filter-active" :events ["onClick"]} "active"]
-                                          [:button {:id "filter-completed" :event-key "filter-completed" :events ["onClick"]} "completed"]
-                                          ]))
-                                    )
-                              ]})))
+  (def todo-env {:kn #{{:name "counter" :value 2}
+                       {:name "todo" :id 0 :text "get milk" :order 0}
+                       {:name "todo" :id 1 :text "take books back" :order 1}
+                       {:name "todo" :id 2 :text "cook" :order 2}
+                       {:name "todo-done" :id 0 :done? "false"}
+                       {:name "todo-done" :id 1 :done? "false"}
+                       {:name "todo-done" :id 2 :done? "false"}
+                       {:name "todo-editing" :id 0 :editing? "false"}
+                       {:name "todo-editing" :id 1 :editing? "false"}
+                       {:name "todo-editing" :id 2 :editing? "false"}
+                       {:name :todo/current-text :value ""}
+                       {:name :todo/filter :value "all"}
+                       {:name :todo/toggle-all :value "false"}
+                       }
+                 :cleanup-rules (concat ui-cleanup-rules
+                                        [(rule ^disp {:name :todo/displayed}
+                                               (- disp))])
+                 :tick-rules [;;on change
+                              (rule {:name :ui/onChange :id "todo-input" :value v}
+                                    (> {:name :todo/current-text} {:value v}))
+
+                              ;;submit
+                              (rule {:name :ui/onClick :id "add-todo"}
+                                    (+ {:name :todo/new!}))
+                              (rule {:name :ui/onKeyDown :id "todo-input" :keyCode 13}
+                                    (+ {:name :todo/new!}))
+
+                              ;;add a new todo
+                              (rule {:name :todo/new!}
+                                    {:name "counter" :value v}
+                                    {:name :todo/current-text :value text}
+                                    (= new-count [v] (inc v))
+                                    (- {:name :todo/new!})
+                                    (> {:name "counter"} {:value new-count})
+                                    (> {:name :todo/current-text} {:value ""})
+                                    (+ {:name "todo" :id new-count :text text :order new-count})
+                                    (+ {:name "todo-editing" :id new-count :editing? "false"})
+                                    (+ {:name "todo-done" :id new-count :done? "false"}))
+
+                              ;;todo editing
+                              (rule {:name :ui/onDoubleClick :entity ent}
+                                    {:name "todo-editing" :id ent :editing? "false"}
+                                    (> {:name "todo-editing" :id ent} {:editing? "true"}))
+
+                              (rule {:name :ui/onBlur :entity ent}
+                                    {:name :todo/edit-text :value v}
+                                    (> {:name "todo" :id ent} {:text v})
+                                    (> {:name "todo-editing" :id ent} {:editing? "false"}))
+
+                              (rule {:name :ui/onChange :id "todo-editor" :value v}
+                                    (> {:name :todo/edit-text} {:value v})
+                                    (+ {:name :todo/edit-text :value v}))
+
+                              (rule {:name :ui/onKeyDown :id "todo-editor" :keyCode 13 :entity ent}
+                                    {:name :todo/edit-text :value new-value}
+                                    (> {:name "todo" :id ent} {:text new-value})
+                                    (> {:name "todo-editing" :id ent} {:editing? "false"}))
+
+                              (rule {:name :ui/onChange :event-key "todo-checkbox" :entity ent :value v}
+                                    (> {:name "todo-done" :id ent} {:done? v}))
+
+                              (rule {:name :ui/onClick :event-key "filter-all"}
+                                    (> {:name :todo/filter} {:value "all"}))
+                              (rule {:name :ui/onClick :event-key "filter-active"}
+                                    (> {:name :todo/filter} {:value "false"}))
+                              (rule {:name :ui/onClick :event-key "filter-completed"}
+                                    (> {:name :todo/filter} {:value "true"}))
+
+                              (rule {:name :ui/onChange :event-key "toggle-all" :value v}
+                                    (> {:name :todo/toggle-all} {:value v}))
+
+                              (rule {:name "todo-done" :id id}
+                                    {:name :ui/onChange :event-key "toggle-all" :value v}
+                                    (> {:name "todo-done" :id id} {:done? v}))
+
+                              (rule {:name :ui/onClick :event-key "clear completed"}
+                                    {:name "todo-done" :id ent :done? "true"}
+                                    (+ {:name :todo/remove! :id ent}))
+
+                              (rule {:name :ui/onClick :event-key "todo-remove" :entity ent}
+                                    (+ {:name :todo/remove! :id ent}))
+
+                              (rule {:name :todo/remove! :id id}
+                                    ^todo {:name "todo" :id id}
+                                    ^done {:name "todo-done" :id id}
+                                    ^editing {:name "todo-editing" :id id}
+                                    (- todo)
+                                    (- done)
+                                    (- editing))]
+
+                 :rules [(rule {:name "todo" :id id}
+                               {:name :todo/filter :value "all"}
+                               (+ {:name :todo/displayed :id id}))
+                         (rule {:name "todo" :id id}
+                               {:name :todo/filter :value v}
+                               {:name "todo-done" :id id :done? v}
+                               (+ {:name :todo/displayed :id id}))
+
+                         (rule {:name :todo/displayed :id id}
+                               {:name "todo" :id id :text text :order order}
+                               {:name "todo-done" :id id :done? done}
+                               (= parent-id [id] (str "todo" id))
+                               (= child-id [id] (str "todo-checkbox" id))
+                               (+s [child-id id done]
+                                   (hiccup
+                                    [:input {:id child-id
+                                             :event-key "todo-checkbox"
+                                             :entity id
+                                             :checked done
+                                             :events ["onChange"]
+                                             :type "checkbox"}]))
+                               (+ {:name :ui/child :id parent-id :child child-id :pos -1}))
+                         (rule {:name :todo/displayed :id id}
+                               {:name "todo" :id id :text text :order order}
+                               {:name "todo-editing" :id id :editing? "false"}
+                               (+s [id text]
+                                   (hiccup
+                                    [:li {:id (str "todo" id) :entity id :event-key "todo" :events ["onDoubleClick"]}
+                                     text
+                                     [:button {:id (str "todo-remove" id) :style {:margin-left "10px"} :entity id :event-key "todo-remove" :events ["onClick"]} "x"]]))
+                               (= child-id [id] (str "todo" id))
+                               (+ {:name :ui/child :id "todo-list" :child child-id :pos order}))
+                         (rule {:name :todo/displayed :id id}
+                               {:name "todo" :id id :text text :order order}
+                               {:name "todo-editing" :id id :editing? "true"}
+                               (+s [id text]
+                                   (hiccup
+                                    [:input {:id (str "todo-editor") :entity id :event-key "todo-editor" :defaultValue text :events ["onChange" "onKeyDown" "onBlur"]}]))
+                               (+ {:name :ui/child :id "todo-list" :child "todo-editor" :pos order}))
+
+                         (rule {:name :todo/current-text :value v}
+                               (+s []
+                                   (hiccup
+                                    [:input {:id "todo-input" :value v :event-key "todo-input" :events ["onChange" "onKeyDown"] :placeholder "What do you need to do?"}]))
+                               (+ {:name :ui/child :id "app" :child "todo-input" :pos 1}))
+
+                         (rule (set remaining [id]
+                                    {:name "todo-done" :id id :done? "false"})
+                               (= left [remaining] (count remaining))
+                               (= text [left] (if (= left 1)
+                                                " todo "
+                                                " todos "))
+                               (+s [left text]
+                                   (hiccup [:span {:id "remaining-count"} left text "left"]))
+                               (+ {:name :ui/child :id "app" :child "remaining-count" :pos 3.5}))
+
+                         (rule (set completed [id]
+                                    {:name "todo-done" :id id :done? "true"})
+                               (= left [completed] (count completed))
+                               (? [left] (> left 0))
+                               (+s [left]
+                                   (hiccup [:span {:id "completed-count" :event-key "clear completed" :events ["onClick"]} "clear completed (" left ")"]))
+                               (+ {:name :ui/child :id "app" :child "completed-count" :pos 7}))
+
+                         (rule {:name :todo/toggle-all :value toggle}
+                               (+s [toggle]
+                                   (hiccup
+                                    [:div {:id "app"}
+                                     [:h1 {:id "todo-header"} "Todos"]
+                                     [:input {:id "toggle-all"
+                                              :event-key "toggle-all"
+                                              :checked toggle
+                                              :events ["onChange"]
+                                              :type "checkbox"}]
+                                     [:button {:id "add-todo" :event-key "add-todo" :events ["onClick"]} "add"]
+                                     [:ul {:id "todo-list"}]
+                                     [:button {:id "filter-all" :event-key "filter-all" :events ["onClick"]} "all"]
+                                     [:button {:id "filter-active" :event-key "filter-active" :events ["onClick"]} "active"]
+                                     [:button {:id "filter-completed" :event-key "filter-completed" :events ["onClick"]} "completed"]
+                                     ]))
+                               )
+                         ]})
+
+  (def todo (run-env todo-env)))

 ;; (go-to-do)
 ;; (js/setTimeout go-to-do 5000)


simple domain map at root is working - it seems like there should be a more elegant way with handlers or something, but this'll do for now.

--- src/smallblog/core.clj
+++ src/smallblog/core.clj
@@ -6,6 +6,7 @@
 				[ring.middleware.params]
 				[ring.middleware.multipart-params]
 				[ring.middleware.stacktrace]
+				[clojure.stacktrace] ; XXX
 				[sandbar stateful-session auth validation])
 	(:require	[compojure.route :as route]
 				[compojure.handler :as handler]
@@ -92,10 +93,25 @@
 (defn ensure-secure [request]
 	(= :https (:scheme request)))

+(defn render-html-posts-helper [blogid request]
+	(render-html-posts
+		(data/get-posts blogid 10 0)
+		(util/uri-from-request request)
+		(:title (data/get-blog blogid))
+		blogid))

 (defroutes main-routes
-	(GET "/" [] (index-page))
+	(GET "/" [:as request]
+		(let [server-name (str
+						(:server-name request)
+						(if (not (nil? (:server-port request)))
+							(str ":" (:server-port request))))
+				uri (:uri request)]
+			(let [domain (data/get-domain server-name)]
+				(if (not (nil? domain))
+					(render-html-posts-helper (:blogid domain) request)
+					(index-page)))))

 	; "account urls"
 	(GET templates/*permission-denied-uri* [] (permission-denied))
@@ -148,12 +164,8 @@

 	; "post urls"
-	(GET "/blog/:bid/post/" [bid :as request]
-		(render-html-posts
-				(data/get-posts (Integer/parseInt bid) 10 0)
-				(util/uri-from-request request)
-				(:title (data/get-blog (Integer/parseInt bid)))
-				bid))
+	(GET "/blog/:blogid/post/" [blogid :as request]
+		(render-html-posts-helper (Integer/parseInt blogid) request))
 	(GET "/blog/:bid/post/new" [bid]
 		(if (not (data/blog-owner? bid))
 			(redirect templates/*permission-denied-uri*)
@@ -224,11 +236,14 @@
 		(wrap-params)
 		(wrap-json-params)))

-(defn -main []
+(defn start-server [join]
 	(let [port (System/getenv "PORT")
 			port (if (nil? port) "3000" port)
 			port (Integer/parseInt port)
 			ssl-port templates/*https-port*]
 		(jetty/run-jetty (app port ssl-port)
-				{:port port :ssl-port ssl-port
+				{:join? join :port port :ssl-port ssl-port
 						:keystore "devonly.keystore" :key-password "foobar"})))
+
+(defn -main []
+	(start-server true))


logging and diagnostics

logging and diagnostics

--- src/babel/english/writer.clj
+++ src/babel/english/writer.clj
@@ -41,12 +41,11 @@
         debug (log/debug (str "using root:" root))
         debug (log/debug (str "using spec:" (strip-refs spec)))

-;;        use-map-fn map ;; <- development
-        use-map-fn pmap ;; <- production
+        use-map-fn map ;; <- development
+;;        use-map-fn pmap ;; <- production

         model (-> ((-> models :en)) deref)
         type-of-model (type model)
-        log-the-type (log/info (str "type of model is: " type-of-model))
         source-expressions (read-all spec
                                      source-language-short-name)]
     (count
@@ -71,9 +70,8 @@
                     existing-english-expression)
                   ;; else, no existing expression: generate a new one.
                   (do
-                    (log/debug (str "generating from spec: " spec))
-                    (log/info (str "generating using source expression: '"
-                                   (:surface source-expression) "'"))
+                    (log/debug (str "calling (process) with spec:" spec "; using source expression: '"
+                                    (:surface source-expression) "'"))
                     (try
                       (let [result
                             (process [{:fill-one-language
@@ -87,7 +85,7 @@
                         ;; of what the (process) command did.
                         (log/debug (str "process result:" result)))
                       (catch Exception e
-                        (let [catch-and-log-error true] ;; false: throw error and stop further generation; true: log/error and continue generation
+                        (let [allow-generation-error false] ;; false: throw error and stop further generation; true: log/error and continue generation
                           (log/error (str "Could not translate source expression: "
                                           "'" (get source-expression :surface) "'"
                                           " from language: '" source-language-short-name
@@ -102,7 +100,7 @@
                                                               [:structure :synsem :sem]))
                                           "'" " ; exception: " e))
                           (cond
-                            catch-and-log-error
+                            allow-generation-error
                             (log/info (str "ignoring above error and continuing."))
                             true
                             (throw e)))))))))))
@@ -111,7 +109,6 @@
 (defn write-one [spec]
   (log/debug (str "generating from spec: " spec))
   (let [model (-> ((-> models :en)) deref)]
-    (log/debug (str "type of model is:" (type model)))
     (try
       (process [{:fill-one-language
                  {:count 1


implemented ack callbacks

implemented ack callbacks

--- src/engine/server/socket_io.clj
+++ src/engine/server/socket_io.clj
@@ -39,6 +39,24 @@
 (defn translate-message-type [type]
   (message-types (Integer/parseInt type)))

+(let [message-splitter #"^([^\+]*)(?:\+?(.*))"]
+  (defn translate-ack [data]
+    (let [[_ id data] (re-matches message-splitter data)]
+      [(Integer/parseInt id) data]))
+  (defn translate-error [data]
+    (rest (re-matches message-splitter data))))
+
+(let [message-scanner #"^(\d):(\d+)?(\+)?:([^:]+)?(?::(.+))?"]
+  (defn translate-message [message]
+    (when message ; receiving nil upon closing, bug in lamina or aleph?
+      (log/debug (format "message is [%s]" message))
+      (if-let [[_ type id data-ack endpoint data] (re-matches message-scanner message)]
+        (let [id (and (not (empty? id))
+                      (Integer/parseInt id))
+              data-ack (not (empty? data-ack))]
+          [(translate-message-type type) id data-ack endpoint data])
+        (log/error (format "Received malformed message %s" message))))))
+
 (defmulti websocket-message (fn [type & rest] (class type)))
 (defmethod websocket-message Integer
   [type & {:keys [id endpoint data] :or {id "" endpoint ""}}]
@@ -52,16 +70,26 @@

 (defn websocket-send [socket type & message-args]
   {:pre [(instance? WebsocketChannel socket)]}
-  (let [seq-args ((:sequencer socket) type message-args)]
-    (enqueue (:channel socket)
+  (let [seq-args ((:sequencer socket) type message-args)
+        channel (:channel socket)
+        endpoint (:endpoint socket)
+        {:keys [id callback]} seq-args]
+    (when (and callback id)
+      (receive (->> channel
+                    (map* translate-message)
+                    (filter* #(= :ack (first %1))) ; [type _ _ _ _]
+                    (map* #(translate-ack (last %1))) ; [_ _ _ _ data]
+                    (filter* #(= id (first %1))) ; [id data]
+                    (map* second))
+               callback))
+    (enqueue channel
              (apply websocket-message type
-                    (into seq-args [:endpoint (:endpoint socket)])))
-    (:id seq-args)))
+                    (into seq-args [:endpoint endpoint])))))

 (defn websocket-sequencer []
   (let [counter (atom 0)]
     (fn [type message]
-      (if (#{:message :json-message :event} (message-types type))
+      (if (#{:message :json-message :event} type)
         (concat message [:id (swap! counter inc)])
         message))))

@@ -74,11 +102,16 @@
 (defn send-heartbeat [socket]
   (websocket-send socket :heartbeat))

-(defn send-message [socket data]
-  (websocket-send socket :data (message data)))
-
-(defn send-event [socket name args]
-  (websocket-send socket :event :data (encode-json->string {:name name :args args})))
+(defn send-message
+  ([socket data] (websocket-send socket :message :data (message data)))
+  ([socket data callback] (websocket-send socket :message :data (message data) :callback callback)))
+
+(defn send-event
+  ([socket name args]
+     (websocket-send socket :event :data (encode-json->string {:name name :args args})))
+  ([socket name args callback]
+     (websocket-send socket :event :data (encode-json->string {:name name :args args})
+                     :callback callback)))

 (defn send-ack
   ([socket id] (websocket-send socket :ack :data (str id)))
@@ -130,45 +163,32 @@
         (and data data-ack?) (send-ack socket id data)
         id (send-ack socket id)))

-(let [message-scanner #"^(\d):(\d+)?(\+)?:([^:]+)?(?::(.+))?"]
-  (defn translate-message [message]
-    (when message ; receiving nil upon closing, bug in lamina or aleph?
-      (log/debug (format "message is [%s]" message))
-      (if-let [[_ type id data-ack endpoint data] (re-matches message-scanner message)]
-        (let [id (and (not (empty? id))
-                      (Integer/parseInt id))
-              data-ack (not (empty? data-ack))]
-          [(translate-message-type type) id data-ack endpoint data])
-        (log/error (format "Received malformed message %s" message))))))
-
 (defn message-handler [socket dispatcher]
-  (let [message-splitter #"^([^\+]*)(?:\+?(.*))"]
-    (fn [message]
-      (when-let [[type id data-ack endpoint data] (translate-message message)]
-        (case type
-          :disconnect (close (:channel socket))
-          :connect (send-error socket "Additional endpoints not supported" "Just don't try again, bitch!")
-          :heartbeat (log/debug "Client sent heartbeat")
-          :message (do
-                     (log/debug (str "Client sent message " data))
-                     (handle-ack socket id (dispatcher "message" data) data-ack))
-          :json-message (do
-                          (log/debug (str "Client sent JSON message " data))
-                          (handle-ack socket id (apply dispatcher "message" (decode-json data)) data-ack))
-          :event (do
-                   (log/debug (str "Client sent event message " data))
-                   (let [{:keys [name args]} (decode-json data)]
-                     (if (reserved-event-types name)
-                       (send-error socket (format "Event name %s is reserved" name))
-                       (handle-ack socket id (apply dispatcher name args) data-ack))))
-          :ack  (let [[_ id data] (re-matches message-splitter data)
-                      id (Integer/parseInt id)]
-                  (log/debug (format "Client acknowledged %d\nData: %s" id data))
-                  (apply dispatcher "ack" id (decode-json data)))
-          :error (let [[_ reason advice] (re-matches message-splitter data)]
-                   (log/error (format "Client signalled an error %s\nAdvice: %s" reason advice)))
-          :noop (log/debug "Client sent noop (whatever)")
-          (log/error (format "Ignoring unknown type %s for message %s" type message)))))))
+  (fn [message]
+    (when-let [[type id data-ack endpoint data] (translate-message message)]
+      (case type
+        :disconnect (close (:channel socket))
+        :connect (send-error socket "Additional endpoints not supported" "Just don't try again, bitch!")
+        :heartbeat (log/debug "Client sent heartbeat")
+        :message (do
+                   (log/debug (str "Client sent message " data))
+                   (handle-ack socket id (dispatcher "message" data) data-ack))
+        :json-message (do
+                        (log/debug (str "Client sent JSON message " data))
+                        (handle-ack socket id (apply dispatcher "message" (decode-json data)) data-ack))
+        :event (do
+                 (log/debug (str "Client sent event message " data))
+                 (let [{:keys [name args]} (decode-json data)]
+                   (if (reserved-event-types name)
+                     (send-error socket (format "Event name %s is reserved" name))
+                     (handle-ack socket id (apply dispatcher name args) data-ack))))
+        :ack  (let [[id data] (translate-ack data)]
+                (log/debug (format "Client acknowledged %d\nData: %s" id data))
+                (apply dispatcher "ack" id (decode-json data)))
+        :error (let [[reason advice] (translate-error data)]
+                 (log/error (format "Client signalled an error %s\nAdvice: %s" reason advice)))
+        :noop (log/debug "Client sent noop (whatever)")
+        (log/error (format "Ignoring unknown type %s for message %s" type message))))))

 (defn socket [dispatcher]
   (fn [channel request]


Policies can now specify a principal for role assuming

--- src/terraboot/core.clj
+++ src/terraboot/core.clj
@@ -337,19 +337,24 @@
               (apply merge-in (map #(elb (:name %) cluster-resource %) (spec :elb)))
               (apply merge-in (map #(alb name-fn %) (spec :alb))))))

-(def default-assume-policy
+
+(defn assume-policy
+  [principals]
   (to-json {"Statement" [{"Action" ["sts:AssumeRole"]
                           "Effect" "Allow"
-                          "Principal" {"Service" ["ec2.amazonaws.com"]}}]
+                          "Principal" {"Service" principals}}]
             "Version" "2012-10-17" }))
+
+(def default-assume-policy (assume-policy ["ec2.amazonaws.com"]))

 (defn iam-role [name name-fn & policies]
   (let [cluster-resource (partial resource name-fn)
-        cluster-id-of (fn [type name] (id-of type (name-fn name)))]
+        cluster-id-of (fn [type name] (id-of type (name-fn name)))
+        principals (distinct (mapv #(:principal % "ec2.amazonaws.com") policies))]
     (merge-in
      (cluster-resource "aws_iam_role" name
                        {:name name
-                        :assume_role_policy default-assume-policy
+                        :assume_role_policy (assume-policy principals)
                         :path "/"})
      (apply merge-in (mapv
                       #(cond
@@ -357,9 +362,8 @@
                                                        (assoc % :role (cluster-id-of "aws_iam_role" name)))
                          (:policy_arn %) (cluster-resource "aws_iam_policy_attachment" (:name %)
                                                            (assoc % :roles [(cluster-id-of "aws_iam_role" name)])))
-                      policies)))
-
-    ))
+                      (map #(dissoc % :principal) policies))))))
+
 (defn policy [statement]
   (let [default-policy {"Version" "2012-10-17"
                         "Statement" {"Effect" "Allow"


infix style formatting of operators

infix style formatting of operators

--- src/thesis/algebra.clj
+++ src/thesis/algebra.clj
@@ -5,16 +5,35 @@
   numeric and boolean primitive constants"
   (:require [clojure.string :as s]))

+(def operator-labels
+  {
+   :not "¬"
+   :and "∧"
+   :or "∨"
+   :implies "⇒"
+  })
 (defrecord Expression
   [operator params]

   Object
   (toString [this]
-    (str "("
-         (-> this :operator name s/upper-case)
-         " "
-         (s/join " " (map str (:params this)))
-         ")")))
+    (let [operator (:operator this)
+          operator-label (get operator-labels operator (-> operator name s/upper-case))
+          first-param (str (first (:params this)))
+          second-param (str (second (:params this)))]
+      (if (< 1 (count (:params this)))
+        (str "("
+             first-param
+             " "
+             operator-label
+             " "
+             second-param
+
+             ")")
+        (str
+          operator-label
+          first-param
+          )))))

 (defmethod print-method Expression [expr ^java.io.Writer writer]
   (.write writer (str expr)))


Use uncontrolled inputs

Use uncontrolled inputs

--- src/chat/cljs/virt/chat.cljs
+++ src/chat/cljs/virt/chat.cljs
@@ -63,15 +63,15 @@
           #js {:onSubmit
                (fn [e]
                  (.preventDefault e)
-                 (let [msg (om/get-state owner :value)]
+                 (let [message-input (om/get-node owner "message-input")
+                       msg (.-value message-input)]
                    (if-not (empty? msg)
                      (do
                        #_(om/transact! channel :messages
                                        #(conj % msg))
                        (put! (om/get-state owner :comm) [:send-message msg])
-                       (om/set-state! owner :value "")))))}
-          (dom/input #js {:onChange (fn [e] (om/set-state! owner :value (.-value (.-target e))))
-                          :value (om/get-state owner :value)}))))))
+                       (set! (.-value message-input) "")))))}
+          (dom/input #js {:ref "message-input"}))))))

 (defn branch-channel [app owner]
   (reify
@@ -94,15 +94,14 @@
     om/IRenderState
     (render-state [_ {:keys [comm]}]
       (dom/form #js {:className "new-channel"}
-        (dom/input #js {:placeholder "Title"
-                        :onChange (fn [e] (om/set-state! owner :title (.-value (.-target e))))
-                        :title (om/get-state owner :title)
-                        :autoFocus true})
-        (dom/button #js {:className "transparent-button"
-                         :onClick (fn [e]
-                                    (.preventDefault e)
-                                    (put! comm [:new-channel (om/get-state owner :title)]))}
-                    "Create")))))
+        (dom/input #js {:ref "new-channel-input" :placeholder "Title" :autoFocus true})
+        (dom/button
+          #js {:className "transparent-button"
+               :onClick (fn [e]
+                          (.preventDefault e)
+                          (put! comm [:new-channel
+                                      (.-value (om/get-node owner "new-channel-input"))]))}
+          "Create")))))

 (defn main [app owner]


Add info print-line after service starts

--- src/clj/dictionator/core.clj
+++ src/clj/dictionator/core.clj
@@ -7,5 +7,6 @@
   "starts the Dictionator webservice"
   [& args]
   (let [[port] args]
+    (println (format "Starting Dictionator webservice on port: %s" port))
     (component/start
      (app/prod-system {:web-port 3000}))))


Type hints.

Type hints.

--- src/clj/fleetdb/embedded.clj
+++ src/clj/fleetdb/embedded.clj
@@ -24,7 +24,7 @@
   (first (core/query* db q)))

 (defn- check-log [read-path]
-  (let [f      (File. read-path)
+  (let [f      (File. #^String read-path)
         raf    (RandomAccessFile. f "rw")
         last-i (dec (.length f))]
     (.seek raf last-i)
@@ -46,7 +46,7 @@

 (defn- new-writer [write-path]
   (let [appending (file/exist? write-path)]
-    (BufferedWriter. (FileWriter. #^String write-path appending))))
+    (BufferedWriter. (FileWriter. #^String write-path #^Boolean appending))))

 (defn- close-writer [#^BufferedWriter writer]
   (.close writer))