Multi job bug where input is incorrectly sealed Seal channel was was being signalled when an input was being sealed for a job other than the one that the task is currently on. This would lead to one job completing and causing another job to incorrectly complete in response.

--- src/onyx/log/commands/common.clj
+++ src/onyx/log/commands/common.clj
@@ -87,10 +87,14 @@
       (let [n (mod message-id (count peers))]
         (= (nth peers n) id)))))

+(defn allocated-to-job [replica args id])
+
 (defn should-seal? [replica args state message-id]
-  (and (all-inputs-exhausted? replica (:job args))
-       (executing-output-task? replica (:id state))
-       (elected-sealer? replica message-id (:id state))))
+  (let [allocated-to-job? (= (:job args) (:job (peer->allocated-job (:allocations replica) (:id state))))]
+    (and allocated-to-job?
+         (all-inputs-exhausted? replica (:job args))
+         (executing-output-task? replica (:id state))
+         (elected-sealer? replica message-id (:id state)))))

 (defn at-least-one-active? [replica peers]
   (->> peers


Throw original exception.

Throw original exception.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -618,7 +618,8 @@
                transform/apply-fn-single)
         throw-fn (if (empty? (:onyx.core/flow-conditions event))
                    (fn [e]
-                     (throw e))
+                     (let [{:keys [exception segment]} (ex-data e)]
+                       (throw (r/maybe-attach-segment exception (:onyx.core/task-id event) segment))))
                    (fn [e]
                      e))]
     (fn [state]


When evicting non-responding peer, evict ourselves as we may also be at fault.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -771,11 +771,18 @@
                  (not (get evicted peer-id)))
         (set! evicted (conj evicted peer-id))
         (let [peer-id (coordinator-peer-id->peer-id peer-id)
+              ;; Evict ourselves, as we're not sure whether it's the other peer at fault, or ourselves
+              ;; and we may be evicting the peer that would have evicted us.
+              evict-self-entry {:fn :leave-cluster
+                                :peer-parent id
+                                :args {:id id
+                                       :group-id (get-in replica [:groups-reverse-index id])}}
               entry {:fn :leave-cluster
                      :peer-parent id
                      :args {:id peer-id
                             :group-id (get-in replica [:groups-reverse-index peer-id])}}]
           (info log-prefix "Peer timed out with no heartbeats. Emitting leave cluster." entry)
+          (>!! outbox-ch evict-self-entry)
           (>!! outbox-ch entry))))
     this)
   (reset-event! [this]


Checkpoint recover WIP

Checkpoint recover WIP

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -220,8 +220,8 @@
   (get-in replica [:task-slot-ids job-id task-id id]))

 (defn checkpoint-path
-  [{:keys [task-id] :as event} replica-version epoch]
-  [[replica-version epoch] [task-id (event->slot-id event)]])
+  [{:keys [task-id job-id] :as event} replica-version epoch]
+  [job-id [replica-version epoch] [task-id (event->slot-id event)]])

 (defn required-checkpoints [replica job-id]
   (mapcat (fn [[task-id peer->slot]]
@@ -230,10 +230,39 @@
                  (vals peer->slot)))
           (get-in replica [:task-slot-ids job-id])))

-; (defn restore-input-checkpoint
-;   [{:keys [job-id] :as event} prev-replica next-replica]
-;   (required-checkpoints prev-replica job-id)
-;   )
+(defn max-complete-checkpoint [store replica job-id]
+  (let [required (set (required-checkpoints replica job-id))]
+    (->> job-id
+         (get store)
+         (filter (fn [[k v]]
+                   (= required (set (keys v)))))
+         (sort (comparator (fn [[r1 e1] [r2 e2]]
+                             (let [r-cmp (compare r1 r2)]
+                               (if (zero? r-cmp)
+                                 (compare e1 e2)
+                                 r-cmp))))))))
+
+; (get-in {:task-slot-ids {:j1 {:t1 1}}} [:task-slot-ids :j1])
+
+; (max-complete-checkpoint
+;  {:j1 {[2 2] {[:t1 1] 8}
+;        [1 7] {[:t1 1] 4}
+;        [2 1] {[:t1 1] 5}
+;        [1 1] {[:t1 1] 3}}}
+;  {:task-slot-ids {:j1 {:t1 {:p1 1}}}}
+;  :j1)
+
+(defn restore-input-checkpoint
+  [{:keys [job-id] :as event} prev-replica next-replica]
+  (when (and (some #{job-id} (:jobs prev-replica))
+             (not= (required-checkpoints prev-replica job-id)
+                   (required-checkpoints next-replica job-id)))
+    (throw (ex-info "Slots for input tasks must currently be stable to allow checkpoint resume" {})))
+
+  ;; Get what checkpoint task-id / slot-ids are required
+  ;; Then go over all the checkpoints and get the one with biggest replica-version/epoch where all of the
+  (required-checkpoints prev-replica job-id)
+  )

 (defn store-input-checkpoint
   [store event replica-version epoch checkpoint]


oncomplete doesn't take any args

oncomplete doesn't take any args

--- src/pc/http/immutant_adapter.clj
+++ src/pc/http/immutant_adapter.clj
@@ -17,7 +17,7 @@
                                                                   (on-complete))})))]
       (when (and (not queued?)
                  on-complete)
-        (on-complete ::closed)))))
+        (on-complete)))))

 (deftype ImmutantAsyncNetworkChannelAdapter []
   i/IAsyncNetworkChannelAdapter


Added file support

Added file support

--- planck-cljs/src/planck/io.cljs
+++ planck-cljs/src/planck/io.cljs
@@ -173,3 +173,18 @@
   [filename content]
   (js/PLANCK_WRITE_FILE filename content)
   nil)
+
+(defn file
+  "Returns a PLKFile, passing each arg to as-file.  Multiple-arg
+   versions treat the first argument as parent and subsequent args as
+   children relative to the parent."
+  ([arg]
+    (js/PLANCK_IO_FILE arg))
+  ([parent & more]
+     (js/PLANCK_IO_FILE (apply str parent more))))
+
+(defn delete-file
+  "Delete file f."
+  [f]
+  (.deleteFile f))
+


RS+CM | #40 | Use korma entity mappings to refer to postgres tables

--- integration/objective8/db/storage_tests.clj
+++ integration/objective8/db/storage_tests.clj
@@ -2,15 +2,16 @@
   (:require [midje.sweet :refer :all]
             [korma.core :as korma]
             [objective8.storage.storage :as storage]
-            [objective8.storage.database :as db]))
+            [objective8.storage.database :as db]
+            [objective8.storage.mappings :as m]))

 (defn db-connection [] (db/connect! db/postgres-spec))

 (defn truncate-tables []
-  (korma/delete :comments)
-  (korma/delete :objectives)
-  (korma/delete :users))
+  (korma/delete m/comment)
+  (korma/delete m/objective)
+  (korma/delete m/user))

 (against-background [(before :contents (db-connection)) (after :facts (truncate-tables))]
 (facts "Storage tests" :integration


clojure: fixed an issue in the morphism function

--- clojure/org/gavrog/clojure/pgraph_morphisms.clj
+++ clojure/org/gavrog/clojure/pgraph_morphisms.clj
@@ -119,8 +119,11 @@
 (defn morphism
   ([net v w M sigs]
     (when (.isUnimodularIntegerMatrix M)
-      (let [d (.minus (first (first (sigs w))) (first (first (sigs v))))
-            op (.times (Operator. (extend-matrix M)) (Operator. d))]
+      (let [M* (Operator. (extend-matrix M))
+            pv (first (first (sigs v)))
+            pw (first (first (sigs w)))
+            d (.minus pw (.times pv M*))
+            op (.times M* (Operator. d))]
         (loop [src2img {}
                q (conj empty-queue [v w])]
           (let [[a b] (first q)]
@@ -163,18 +166,18 @@
 (defn spacegroup [net]
   (SpaceGroup. (.getDimension net) (map first (symmetries net))))

+(defn systreable? [net]
+  (and (.isLocallyStable net) (not (.hasSecondOrderCollisions net))))
+
+(defn test-net [net]
+  (let [n1 (when (systreable? net) (.getName (.getSpaceGroup net)))
+        n2 (when (node-signatures net) (.getName (spacegroup net)))
+        good (or (nil? n1) (= n1 n2))]
+    (when (not good) (println net n1 n2))
+    good))
+

 (deftest spacegroup-test
-  (defn systreable? [net]
-    (and (.isLocallyStable net) (not (.hasSecondOrderCollisions net))))
-
-  (defn test-net [net]
-    (let [n1 (when (systreable? net) (.getName (.getSpaceGroup net)))
-          n2 (when (node-signatures net) (.getName (spacegroup net)))
-          good (or (nil? n1) (= n1 n2))]
-      (when (not good) (println n1 n2))
-      good))
-
   (doseq [f ["dia.pgr", "test.pgr", "Fivecases.cgd", "xbad.pgr"]
           g (nets f)]
         (is (test-net g))))


CMR-3797: Another try to fix the build error.

--- system-int-test/src/cmr/system_int_test/utils/search_util.clj
+++ system-int-test/src/cmr/system_int_test/utils/search_util.clj
@@ -14,7 +14,6 @@
     [cmr.common-app.test.side-api :as side]
     [cmr.common.concepts :as cs]
     [cmr.common.mime-types :as mime-types]
-    [cmr.common.test.time-util :as tu]
     [cmr.common.time-keeper :as tk]
     [cmr.common.util :as util]
     [cmr.common.xml :as cx]
@@ -637,20 +636,19 @@
      (:body response)
      response)))

-(def now-n
-  "The N value for the current time. Uses N values for date times as describd in
-  cmr.common.test.time-util. Need to use this common now-n to lock both the current time
-  in test and on CMR side."
-  10)
+(def common-now
+  " Need to use this common now-n to lock both the current time
+    in test and on CMR side."
+  (tk/now))

 (defn freeze-resume-time-fixture
   []
   (fn [f]
     (try
       ;; Freeze time in test
-      (tk/set-time-override! (tu/n->date-time now-n))
+      (tk/set-time-override! common-now)
       ;; Freeze time on CMR side
-      (side/eval-form `(tk/set-time-override! (tu/n->date-time now-n)))
+      (side/eval-form `(tk/set-time-override! common-now))
       (f)
       (finally
         ;; Resume time in test


Exclude PDFs.

Exclude PDFs.

--- src/member_domains/lookup.clj
+++ src/member_domains/lookup.clj
@@ -264,9 +264,9 @@
   "Take a URL and try to resolve it to find what valid DOI it corresponds to."
   [url]
   (info "Attempt resolve-doi-from-url: " url)
-
+  ; No hope for PDFs.
+  (when-not (.endsWith url ".pdf")
   ; Check if we want to bother with this URL.
-
     (when-let [result (try-try-again {:sleep 500 :tries 2} #(fetch url))]
       (let [body (:body result)

@@ -285,7 +285,7 @@
         (info "Found from structured HTML:", doi-from-structured)
         (info "Found from unstructured text:" doi-from-unstructured)
         (info "Valid DOI: " valid-doi)
-        valid-doi)))
+        valid-doi))))

 ; Combined methods.
 ; Combine extraction methods and validate.


simplify remove-comments implementation

simplify remove-comments implementation

--- src/semantic_csv/transducers.clj
+++ src/semantic_csv/transducers.clj
@@ -115,18 +115,10 @@
   before mappify."
   ([] (remove-comments {:comment-re #"^\#"}))
   ([{:as opts :keys [comment-re comment-char]}]
-   (fn [rf]
-     (let [commented? (if comment-char
-                        #(= comment-char (first %))
-                        (partial re-find comment-re))]
-       (fn
-         ([] (rf))
-         ([results] (rf results))
-         ([results input]
-          (let [x (first input)]
-            (if (and x (commented? x))
-              results
-              (rf results input)))))))))
+   (let [commented? (if comment-char
+                      #(= comment-char (first %))
+                      (partial re-find comment-re))]
+     (remove (comp commented? first)))))

 ;; Let's see this in action.
 ;;
@@ -268,7 +260,7 @@
                    :as   opts}]
   (let [rest-options (dissoc opts :parser-opts)]
     (into [] (process rest-options)
-     (impl/apply-kwargs csv/parse-csv csv-readable parser-opts))))
+      (impl/apply-kwargs csv/parse-csv csv-readable parser-opts))))

 ;; Now our example becomes:
@@ -289,7 +281,7 @@
   [csv-filename & {:as opts}]
   (let [rest-options (dissoc opts :parser-opts)]
     (with-open [in-file (io/reader csv-filename)]
-       (impl/apply-kwargs parse-and-process in-file opts))))
+      (impl/apply-kwargs parse-and-process in-file opts))))

 ;; For the ultimate in _programmer_ laziness:
 ;;


fixup! wip: display nested object as columns

--- src/metabase/driver/crate.clj
+++ src/metabase/driver/crate.clj
@@ -6,7 +6,7 @@
             [metabase.driver.generic-sql :as sql]
             [metabase.util :as u]
             [clojure.tools.logging :as log])
-  (:import (java.sql DatabaseMetaData)))
+  (:import (java.sql.DatabaseMetaData)))

 (def ^:private ^:const column->base-type
   "Map of Crate column types -> Field base types
@@ -59,17 +59,16 @@

 (defn- describe-table-fields
   [database, driver, {:keys [schema name]}]
-  (set (doseq [{column_name :column_name, type_name :type_name}
-             (jdbc/query
-                 (sql/db->jdbc-connection-spec database)
-                 [(format "select column_name, data_type as type_name
-                  from information_schema.columns
-                  where table_name like '%s' and table_schema like '%s'" name schema)])]
-          (merge {:name      column_name
-                 :custom    {:column-type type_name}
-                 :base-type (or (column->base-type driver (keyword type_name))
-                                (do (log/warn (format "Don't know how to map column type '%s' to a Field base_type, falling back to :type/*." type_name))
-                                    :type/*))}))))
+  (let [columns (jdbc/query
+                  (sql/db->jdbc-connection-spec database)
+                    [(format "select column_name, data_type as type_name from information_schema.columns
+                              where table_name like '%s' and table_schema like '%s'" name schema)])]
+    (set (for [{:keys [column_name type_name]} columns]
+      (merge {:name      column_name
+              :custom    {:column-type type_name}
+              :base-type (or (column->base-type (keyword type_name))
+                           (do (log/warn (format "Don't know how to map column type '%s' to a Field base_type, falling back to :type/*." type_name))
+                             :type/*))})))))

 (defn- add-table-pks
   [^DatabaseMetaData metadata, table]
@@ -85,9 +84,9 @@

 (defn- describe-table [driver database table]
   (sql/with-metadata [metadata driver database]
-                 (->> (assoc (select-keys table [:name :schema]) :fields (describe-table-fields database driver table))
-                      ;; find PKs and mark them
-                      (add-table-pks metadata))))
+    (->> (assoc (select-keys table [:name :schema]) :fields (describe-table-fields database driver table))
+      ;; find PKs and mark them
+      (add-table-pks metadata))))

 (defn- field->alias [field]
   (str \" (name field) \"))


Fix /:user/:apikey and /

Fix /:user/:apikey and /

--- src/multiplex/routes/home.clj
+++ src/multiplex/routes/home.clj
@@ -80,7 +80,8 @@

 (defn render-page-user [params]
   (if-let [usr (muser/get-user-by-key (:apikey params))]
-    (let [posts-map (get-some (:limit params) (:page params) {:author (:uid usr)})]
+    (let [where-clause (if (mpost/valid-itemtype? (:itemtype params)) {:author (:uid usr) :itemtype (:itemtype params)} {:author (:uid usr)})
+          posts-map (get-some (:limit params) (:page params) where-clause)]
       (layout/render "page_user.html" (assoc posts-map :post (assoc usr :avatar (nth config/user-icons (:uid usr))))))
     (if-let [usr (muser/get-user-by-name (:username params))]
       (let [ava (nth config/user-icons (:uid usr))
@@ -192,7 +193,11 @@
   (GET  "/show/:id" [id] (redirect (str "/post/" id) :permanent))
   (GET  "/about" [] (render-page-about))
   (GET  "/about/changes" [] (render-page-changes))
-  (GET  "/user/:username/:apikey" [username apikey] (render-page-user {:username username :apikey apikey}))
-  (GET  "/user/:username" [username page limit type] (render-page-user {:username username :limit (util/int-or-default limit 10) :page (util/int-or-default page 1) :itemtype (util/string-or-default type)}))
-  (GET  "/user/:username/" [username] (redirect (str "/user/" username) :permanent))
-  (GET  "/" [page limit type] (render-page-stream {:limit (util/int-or-default limit 10) :page (util/int-or-default page 1) :itemtype (util/string-or-default type)})))
+  (GET  "/user/:username/:apikey" [username apikey page limit type]
+    (render-page-user {:username username :limit (util/int-or-default limit 10) :page (util/int-or-default page 1) :itemtype (util/string-or-default type) :apikey apikey}))
+  (GET  "/user/:username" [username page limit type]
+    (render-page-user {:username username :limit (util/int-or-default limit 10) :page (util/int-or-default page 1) :itemtype (util/string-or-default type)}))
+  (GET  "/user/:username/" [username]
+    (redirect (str "/user/" username) :permanent))
+  (GET  "/" [page limit type]
+    (render-page-stream {:limit (util/int-or-default limit 10) :page (util/int-or-default page 1) :itemtype (util/string-or-default type)})))


Require clojure.string to clean warning (based on PR comments)

Issue #38
Pull request #39

--- src/obb_rules/simplifier.cljc
+++ src/obb_rules/simplifier.cljc
@@ -2,7 +2,8 @@
   "Simplifies data structures and builds them if necessary"
   (:require [clojure.walk :as w]
             [obb-rules.host-dependent :as host]
-            [obb-rules.unit :as unit]))
+            [obb-rules.unit :as unit]
+            [clojure.string :as string]))

 (declare clean-unit)
 (declare build-unit)
@@ -62,7 +63,7 @@
 (defn coordenize
   "Transforms a string in a coordinate"
   [raw]
-  (let [beter-raw (-> raw (str) (clojure.string/replace #":" ""))]
+  (let [beter-raw (-> raw (str) (string/replace #":" ""))]
     (if-let [parsed (re-matches #"\[(\d+) (\d+)\]" beter-raw)]
       (into [] (map host/parse-int (rest parsed)))
       raw)))


Only delete BK data if flag is set

Only delete BK data if flag is set

--- src/onyx/state/bookkeeper.clj
+++ src/onyx/state/bookkeeper.clj
@@ -55,8 +55,9 @@
   (component/stop [{:keys [server] :as component}]
     (info "Stopping BookKeeper server")
     (.shutdown ^BookieServer server)
-    (cleanup-dir (:journal-dir component))
-    (cleanup-dir (:ledger-dir component))
+    (when (:onyx.bookkeeper/delete-server-data? env-config)
+      (cleanup-dir (:journal-dir component))
+      (cleanup-dir (:ledger-dir component)))
     (assoc component :server nil :port nil :journal-dir nil :ledger-dir nil)))

 (defn started? [bookie]
@@ -76,7 +77,7 @@
                               (reset! bookie (component/start (->Bookie env-config port log)))
                               (catch Throwable t
                                 (error t "Error starting BookKeeper server:"))))
-                          (Thread/sleep 100)))]
+                          (Thread/sleep 1000)))]
       (info "Starting BookKeeper Monitor service")
       (assoc component :bookie bookie :monitor-fut monitor-fut)))
   (component/stop [component]


CMR-3557 Actually fix tests in CI

CMR-3557 Actually fix tests in CI

--- system-int-test/test/cmr/system_int_test/bootstrap/bulk_index_test.clj
+++ system-int-test/test/cmr/system_int_test/bootstrap/bulk_index_test.clj
@@ -194,7 +194,7 @@
      (index/wait-until-indexed)

      ;; ACLs
-     (let [response (ac/search-for-acls (u/conn-context) {:token (tc/echo-system-token)})
+     (let [response (ac/search-for-acls (u/conn-context) {} {:token (tc/echo-system-token)})
            items (:items response)]
        (search-results-match? items [acl1 acl2]))

@@ -267,7 +267,7 @@
          :granule [gran-within-buffer gran-after-date])

        ;; ACLs
-       (let [response (ac/search-for-acls (u/conn-context) {:token (tc/echo-system-token)})
+       (let [response (ac/search-for-acls (u/conn-context) {} {:token (tc/echo-system-token)})
              items (:items response)]
          (search-results-match? items [acl-within-buffer acl-after-date]))

@@ -349,7 +349,7 @@
           :granule [gran2])

         ;; ACLs
-        (let [response (ac/search-for-acls (u/conn-context) {:token (tc/echo-system-token)})
+        (let [response (ac/search-for-acls (u/conn-context) {} {:token (tc/echo-system-token)})
               items (:items response)]
           (search-results-match? items [acl2]))


working on generation

working on generation

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -5,7 +5,7 @@
             [babel.english.grammar :as grammar]
             [babel.english.morphology :refer [fo get-string]]

-            [babel.generate :refer [get-lexemes lightning-bolts]]
+            [babel.generate :refer [get-lexemes lightning-bolts not-fail?]]

             [babel.over :refer [overc overh]]

@@ -584,4 +584,36 @@
 ;; (repeatedly #(println (fo-ps (first (nugents (medium) spec1)))))
 ;; (repeatedly #(println (fo (first (nugents (medium) {:synsem {:cat :noun}})))))

-
+(deftest lbs
+  (let [spec
+        {:modified false
+                   :synsem {:cat :verb
+                            :subcat ()
+                            :sem {:pred :eat
+                                  :tense :present
+                                  :subj {:pred :I}
+                                  :obj :unspec}}}
+
+        lbs (babel.generate/lightning-bolts (medium) spec 0 6)]
+    (is (not (empty? lbs)))))
+
+(def works-ok
+  (map morph (babel.generate/generate-all
+              {:modified false,
+               :synsem {:cat :verb, :subcat (),
+                        :sem {:pred :sleep,
+                              :subj {:pred :tu},
+                              :obj :unspec}}}
+              (medium) 0 6)))
+
+(defn runs-forever []
+  (map morph (babel.generate/generate-all
+              {:modified false,
+               :synsem {:cat :verb, :subcat (),
+                        :sem {:pred :sleep,
+                              :subj {:pred :top},
+                              :obj :unspec}}}
+              (medium) 0 6)))
+
+
+


+(deftest generate-present)

+(deftest generate-present)

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -41,6 +41,15 @@

          true
          (over/over grammar arg1 arg2))))
+
+(deftest generate-present
+  (let [result (engine/generate {:synsem {:subcat '()
+                                          :sem {:pred :sleep
+                                                :subj {:pred :I}
+                                                :tense :present
+                                                :aspect :progressive}}}
+                                small)]
+    (is (= "je dors" (fo result)))))

 (deftest generate-conditional
   (let [result (engine/generate {:synsem {:subcat '()


s/unifyc/unify/

s/unifyc/unify/

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -14,7 +14,7 @@
             #?(:cljs [cljs.test :refer-macros [deftest is]])
             #?(:clj [clojure.tools.logging :as log])
             #?(:cljs [babel.logjs :as log])
-            [dag_unify.core :refer [fail-path fail? get-in strip-refs unifyc]]))
+            [dag_unify.core :refer [fail-path fail? get-in strip-refs unify]]))

 (defn small [] (fr/small))

@@ -92,7 +92,7 @@
         result
         (filter #(not (fail? %))
                 (map (fn [rule]
-                       (unifyc rule
+                       (unify rule
                                {:head (last (get lexicon "être"))}))
                      (:grammar (small))))]
     (is (not (empty? result)))
@@ -177,7 +177,7 @@

 (deftest generate-passe-compose-1
   (let [result
-        (generate (unifyc
+        (generate (unify
                    {:synsem {:subcat '()}}
                    {:synsem {:sem {:subj {:pred :noi
                                           :gender :fem}


Deleted file

Deleted file

--- src/vdquil/chapter4/figure15.clj
+++ src/vdquil/chapter4/figure15.clj
@@ -1,148 +0,0 @@
-
-
-;;TODO find an idiomatic way to implement this tab UI. As is, I'd just be cramming an imperative approach into a functional language. Maybe use Swing directly? Or Seesaw to clojurize Swing?
-
-;; Ben Fry's Visualizing Data, Chapter 4 (Time Series), figure 15:
-;; Clickable tabs
-;; Converted from Processing to Quil as an exercise by Dave Liepmann
-
-(ns vdquil.chapter4.figure15
-  (:use quil.core)
-  (:use vdquil.util)
-  (:use vdquil.chapter4.ch4data)
-  (require [seesaw.core :as seesaw])
-  (require [clojure.set :refer [union]]))
-
-(def current-column (atom 1))
-
-(def time-series-width 720)
-(def time-series-height 405)
-
-(def plotx1 120)
-(def plotx2 (- time-series-width 80))
-(def ploty1 60)
-(def ploty2 (- time-series-height 70))
-
-(def year-min (apply min (map first (rest milk-tea-coffee-data))))
-(def year-max (apply max (map first (rest milk-tea-coffee-data))))
-(def data-min (apply min (apply union (for [x (range 1 4)] (map #(nth % x) (rest milk-tea-coffee-data))))))
-(def year-interval 10)
-(def volume-interval 10)
-(def data-max (* volume-interval (ceil (/ (apply max (apply union (for [x (range 1 4)] (map #(nth % x) (rest milk-tea-coffee-data))))) volume-interval))))
-(def data-first 0)
-
-(def tab-padding 10)
-
-(defn tab-x-starts []
-  (atom  (0 0 0)))
-(defn tab-x-ends []
-  (atom  (0 0 0)))
-(def tab-y-start ploty1)
-(def tab-y-end (- ploty1 40))
-
-(defn setup []
-  (seesaw/native!))
-
-(defn draw-plot-area []
-  (background 224)
-  (smooth)
-  ;; Show the plot area as a white box
-  (fill 255)
-  (no-stroke)
-  (rect-mode :corners)
-  (rect plotx1 ploty1 plotx2 ploty2))
-
-(defn draw-title-tabs []
-  (text-size 20)
-  (text-align :left :baseline)
-  (text-font (create-font "Sans-Serif" 20))
-  (doseq [column (range 1 (count (first milk-tea-coffee-data)))]
-    (let [column-title (nth (first milk-tea-coffee-data) column)
-          tab-x-start (+ 1
-                         plotx1
-                         (* 2 (- column 1) tab-padding)
-                         (reduce + 0 (map #(text-width (nth (first milk-tea-coffee-data) %)) (range 1 column))))
-          tab-x-end (+ tab-x-start (* 2 tab-padding) (text-width column-title))]
-      (reset! (nth tab-x-starts column) tab-x-start)
-      (reset! (nth tab-x-ends column) tab-x-end)
-      (if (= column @current-column)
-        (fill 255)
-        (fill 224))
-      (rect tab-x-start tab-y-start tab-x-end tab-y-end)
-      (if (= column @current-column)
-        (fill 0)
-        (fill 64))
-      (text column-title (+ tab-x-start tab-padding) (- ploty1 10)))))
-
-(defn annotate-x-axis []
-  ;; Draw year labels
-  (text-size 10)
-  (text-align :center :top)
-  (stroke-weight 1)
-  ;; Use thin, gray lines to draw the grid
-  (stroke 224)
-  (doseq [year (range year-min year-max year-interval)]
-    (let [x (map-range year year-min year-max plotx1 plotx2)]
-      (text (str year) x (+ 10 ploty2))
-      (line x ploty1 x ploty2))))
-
-(defn annotate-y-axis []
-  ;; Draw volume labels
-  (text-align :right :center)
-  (doseq [volume (range data-first (+ 1 data-max) volume-interval)]
-    (let [y (map-range volume data-first data-max ploty2 ploty1)]
-      ;; Draw major tick mark
-      (do
-        (stroke 0)
-        (line plotx1 y (- plotx1 4) y)
-        (text-align :right :center) ;; Center vertically
-        (if (= volume data-first) (text-align :right :bottom)) ;; Align the "0" label by the bottom
-        (text (str (ceil volume)) (- plotx1 10) y)))))
-
-(defn draw-axis-labels []
-  ;; Draw axis labels
-  (text-size 13)
-  (text-leading 15)
-  (text-align :center :center)
-  (text "Gallons\nconsumer\nper capita" 50 (/ (+ ploty1 ploty2) 2))
-  (text (str (first (first milk-tea-coffee-data))) (/ (+ plotx1 plotx2) 2) (- (height) 25)))
-
-(defn draw-data-point-area [row]
-  (stroke-weight 2)
-  (no-stroke)
-  (fill (apply color (hex-to-rgb "#5679C1")))
-  (let [[year milk tea coffee] row
-        x (map-range year year-min year-max plotx1 plotx2)
-        y (map-range (nth row @current-column) data-min data-max ploty2 ploty1)]
-    (vertex x y)))
-
-(defn draw []
-  (draw-plot-area)
-  (draw-title-tabs)
-  (annotate-x-axis)
-  (annotate-y-axis)
-  (draw-axis-labels)
-  (begin-shape)
-  (loop [rows (rest milk-tea-coffee-data)]
-    (if (seq rows)
-      (do (draw-data-point-area (first rows))
-          (recur (rest rows)))))
-  (vertex plotx2 ploty2)
-  (vertex plotx1 ploty2)
-  (end-shape))
-
-(defn set-column []
-  (for (range )
-    (if (string? (first columns))
-      (do (if (< (mouse-x) (nth tab-x-starts ))))
-      (recur (rest columns)))))
-
-(defsketch mtc
-  :title "Milk, Tea, Coffee"
-  :setup setup
-  :draw draw
-  :size [time-series-width time-series-height]
-  :mouse-clicked set-column)
-
-;(sketch-close mtc)
-


Add boundaries to selection

Add boundaries to selection

--- src/tabswitcher/handlers.cljs
+++ src/tabswitcher/handlers.cljs
@@ -23,12 +23,19 @@
 (register-handler
   :next-result
   (fn [db _]
-    (update db :selection inc)))
+    (let [boundary  (count (:results db))
+          selection (:selection db)]
+      (if (< selection (- boundary 1))
+        (update db :selection inc)
+        db))))

 (register-handler
   :previous-result
   (fn [db _]
-    (update db :selection dec)))
+    (let [selection (:selection db)]
+      (if (> selection 0)
+        (update db :selection dec)
+        db))))

 (defn fuzzy-find [tabs query]
   (reverse (sort-by #(f/dice (:title %) query) tabs)))


cleanup, remove testcode from todopipeline again

--- src/todopipeline/pipeline.clj
+++ src/todopipeline/pipeline.clj
@@ -8,13 +8,10 @@
 ;; into the system.

 (ns todopipeline.pipeline
-  (:require [lambdacd.server :as server]
-            [lambdacd.execution :as execution]
-            [lambdacd.core :as core]
+  (:require [lambdacd.core :as core]
             [lambdacd.util :as utils]
             [ring.server.standalone :as ring-server]
-            [clojure.tools.logging :as log]
-            [clojure.java.io :as io])
+            [clojure.tools.logging :as log])
   (:use [lambdacd.steps.control-flow]
         [todopipeline.steps]))

@@ -64,7 +61,7 @@

 ;; For this demonstration, we don't care too much about persisting anything over a longer timeframe so we just use a
 ;; temp-directory
-(def home-dir (io/file "/tmp/helloworld"))
+(def home-dir (utils/create-temp-dir))
 (log/info "LambdaCD Home Directory is " home-dir)
 (def config { :home-dir home-dir :dont-wait-for-completion true})


add banner

add banner

--- ccw.core/src/ccw/editors/antlrbased/reload_clojure.clj
+++ ccw.core/src/ccw/editors/antlrbased/reload_clojure.clj
@@ -1,3 +1,14 @@
+; *******************************************************************************
+; * Copyright (c) 2010 Tuomas KARKKAINEN.
+; * All rights reserved. This program and the accompanying materials
+; * are made available under the terms of the Eclipse Public License v1.0
+; * which accompanies this distribution, and is available at
+; * http://www.eclipse.org/legal/epl-v10.html
+; *
+; * Contributors:
+; *    Tuomas KARKKAINEN - initial API and implementation
+; *******************************************************************************/
+
 (ns ccw.editors.antlrbased.reload-clojure
   (:gen-class
     :init init


actually implement error handler

actually implement error handler

--- src/yeller_clojure_client.clj
+++ src/yeller_clojure_client.clj
@@ -1,20 +1,50 @@
 (ns yeller-clojure-client
   (:require [clojure.walk :refer [stringify-keys]])
-  (:import (com.yellerapp.client YellerHTTPClient YellerClient YellerExtraDetail)))
+  (:import (com.yellerapp.client
+             YellerHTTPClient
+             YellerClient
+             YellerExtraDetail)))
+
+(defn default-io-error-handler [backend error]
+  (.println *err* (str "Yeller: an io error ocurred whilst talking to yeller: " error)))
+
+(defn default-auth-error-handler [backend error]
+  (.println *err* (str "Yeller: an authentication error ocurred whilst talking to yeller: " error)))

 (defn ^YellerClient client
   "creates a new client from a map of configuration settings Required settings:
-   {:token \"YOUR API KEY HERE\"}
-   other settings:
-   :error-handler (fn [error] (println error))
-   a function for reporting errors when communicating with yeller's servers
+  {:token \"YOUR API KEY HERE\"}
+
+  other settings:
+  :auth-error-handler (fn [backend error] (println \"Yeller: an authentication error occurred whilst talking to yeller:\" backend error))
+  a function for reporting authentication errors when communicating with
+  yeller's servers. You might want this to print out to a log file (by default
+  it prints to stderr). Takes a String for the hostname of the api server it
+  was talking to during the error, and a Throwable for whatever exception
+  ocurred.
+  :io-error-handler (fn [backend error] (println \"Yeller: an io error occurred whilst talking to yeller:\" backend error))
+  a function for reporting io errors when communicating with
+  yeller's servers. You might want this to print out to a log file (by default
+  it prints to stderr). Takes a String for the hostname of the api server it
+  was talking to during the error, and a Throwable for whatever exception
+  ocurred.
   "
   [options]
   (assert (string? (:token options)) "Yeller client must be passed your api key as a string under :token")
   (let [client (YellerHTTPClient. (:token options))]
-    client
-    )
-  )
+    (if (or (:io-error-handler options)
+            (:auth-error-handler options))
+      (.setErrorHandler
+        client
+        (reify
+          YellerErrorHandler
+          (reportAuthError [backend e]
+            ((:auth-error-handler options default-auth-error-handler)
+               backend e))
+          (reportIOError [backend e]
+            ((:auth-io-handler options default-auth-error-handler)
+               backend e)))))
+    client))

 (defn ^YellerExtraDetail add-url [^YellerExtraDetail detail extra]
   (if (string? (:url extra))


Use edn/read-string for safety

Use edn/read-string for safety

--- desktop/src/nightweb_desktop/utils.clj
+++ desktop/src/nightweb_desktop/utils.clj
@@ -1,5 +1,6 @@
 (ns nightweb-desktop.utils
-  (:require [clojure.java.io :as java.io]
+  (:require [clojure.edn :as edn]
+            [clojure.java.io :as java.io]
             [clojure.xml :as xml]
             [nightweb.constants :as c]
             [nightweb.formats :as f]
@@ -18,7 +19,7 @@
 (defn read-pref
   [k]
   (when-let [string (.get prefs (name k) nil)]
-    (read-string string)))
+    (edn/read-string string)))

 (def update? (atom (read-pref :update)))
 (def remote? (atom (read-pref :remote)))
@@ -79,8 +80,8 @@
   "Returns version number from project.clj."
   []
   (let [project-clj (-> (java.io/resource "project.clj")
-                        (slurp)
-                        (read-string))]
+                        slurp
+                        edn/read-string)]
     (if (= (name (nth project-clj 1)) "nightweb-desktop")
       (nth project-clj 2)
       "beta")))


Sanity check Snow Day.

Sanity check Snow Day.

--- src/clojush/problems/software/benchmarks_v2/snow_day.clj
+++ src/clojush/problems/software/benchmarks_v2/snow_day.clj
@@ -11,19 +11,23 @@

 ; Atom generators
 (def snow-day-atom-generators
-  (concat (list
-            ;;; end constants
-            ;;; end ERCs
-            (tag-instruction-erc [:integer :float :boolean :exec] 1000)
-            (tagged-instruction-erc 1000)
-            ;;; end tag ERCs
-            'in1
-            'in2
-            'in3
-            'in4
-            ;;; end input instructions
-            )
-          (registered-for-stacks [:integer :float :boolean :exec])))
+  (make-proportional-atom-generators
+   (concat
+    (registered-for-stacks [:integer :float :boolean :exec])
+    (list (tag-instruction-erc [:integer :float :boolean :exec] 1000) ; tags
+          (tagged-instruction-erc 1000)))
+   (list 'in1
+         'in2
+         'in3
+         'in4) ; inputs
+   (list 0
+         0.0
+         1
+         1.0
+         -1
+         -1.0) ; constants
+   {:proportion-inputs 0.15
+    :proportion-constants 0.05}))

 ;; A list of data domains for the problem. Each domain is a vector containing
@@ -35,11 +39,17 @@
   [[(list [0 0.0 0.0 0.0]   ; min size
           [15 15.0 15.0 0.15]   ; same number
           [20 19.99 9.999 0.999]    ; max size
+          [20 19.99 9.999 0.0]    ; max snow
+          [10 0.0 1.0 0.0]
+          [8 10.0 2.0 0.0]
+          [13 0.0 0.0 0.0]
+          [15 14.56 0.0 0.0]
+          [16 18.19 0.0 0.05]
           [8 11.3 0.5 0.3]
           [5 1.3 1.5 0.05]
           [10 0.0 2.0 0.0]
-          ) 6 0]
-   [(fn [] (vector (inc (rand-int 20)) (rand 20) (rand 10) (rand))) 194 2000] ; Random cases [13,197]
+          ) 12 0]
+   [(fn [] (vector (rand-int 21) (rand 20) (rand 10) (rand))) 188 2000] ; Random cases
    ])

 ;;Can make Snow Day test data like this:
@@ -51,9 +61,13 @@
    [[input1 input2 input3 input4] output]."
   [inputs]
   (map #(vector %
-    (loop [time (first %) total (second %)]
-      (if (= time 0) total
-                     (recur (dec time) (+ (* total (- 1 (last %))) (nth % 2))))))
+    (loop [time (first %)
+           total (second %)]
+      (if (= time 0)
+        total
+        (recur (dec time)
+               (+ (* total (- 1 (last %)))
+                  (nth % 2))))))
        inputs))

 (defn make-snow-day-error-function-from-cases
@@ -72,10 +86,10 @@
                                                                                [])]
                          (let [final-state (run-push (:program individual)
                                                      (->> (make-push-state)
-                                                       (push-item input4 :input)
-                                                       (push-item input3 :input)
-                                                       (push-item input2 :input)
-                                                       (push-item input1 :input)))
+                                                          (push-item input4 :input)
+                                                          (push-item input3 :input)
+                                                          (push-item input2 :input)
+                                                          (push-item input1 :input)))
                                result (top-item :float final-state)]
                            (when print-outputs
                              (let [res-str (if (float? result)
@@ -87,10 +101,9 @@
                            ; Error is float error rounded to 3 decimal places
                            (round-to-n-decimal-places
                             (if (number? result)
-                              (abs (- result correct-output)) ; distance from correct integer
+                              (abs (- result correct-output)) ; distance from correct float
                               1000000.0) ; penalty for no return value
-                            3)
-                             )))]
+                            3))))]
         (if (= data-cases :train)
           (assoc individual :behaviors @behavior :errors errors)
           (assoc individual :test-errors errors))))))
@@ -99,7 +112,7 @@
   "Returns the train and test cases."
   [data-domains]
   (map snow-day-test-cases
-          (test-and-train-data-from-domains data-domains)))
+       (test-and-train-data-from-domains data-domains)))

 ; Define train and test cases
 (def snow-day-train-and-test-cases
@@ -140,7 +153,7 @@
 ; Define the argmap
 (def argmap
   {:error-function (make-snow-day-error-function-from-cases (first snow-day-train-and-test-cases)
-                                                             (second snow-day-train-and-test-cases))
+                                                            (second snow-day-train-and-test-cases))
    :atom-generators snow-day-atom-generators
    :max-points 2000
    :max-genome-size-in-initial-program 250


Update tests: consistent user, reliable true test

--- test/uruk/core_test.clj
+++ test/uruk/core_test.clj
@@ -47,7 +47,7 @@
     (testing "...with URI, user, password"
       (is (= "Hello world"
              (with-open [session (create-session {:uri "xdbc://localhost:8383/"
-                                                  :user "rest-admin" :password "x"})]
+                                                  :user "test-admin" :password "uruktesting"})]
                (-> session
                    (.submitRequest (.newAdhocQuery session
                                                    "\"Hello world\""))
@@ -264,16 +264,16 @@
       (testing "with hosted content source using user, password, content-base"
         (with-open [sess (create-session
                           db (make-hosted-content-source "localhost" 8383
-                                                         {:user "rest-admin"
-                                                          :password "x"
+                                                         {:user "test-admin"
+                                                          :password "uruktesting"
                                                           :content-base "TutorialDB"})
                           opts)]
           (as-expected-session-config? (session->map sess) opts)))
       (testing "with hosted content source using user and password"
         (with-open [sess (create-session
                           db (make-hosted-content-source "localhost" 8383
-                                                         {:user "rest-admin"
-                                                          :password "x"})
+                                                         {:user "test-admin"
+                                                          :password "uruktesting"})
                           opts)]
           (as-expected-session-config? (session->map sess) opts)))
       ;; TODO once we want to delve into extreme complexity of ConnectionProvider
@@ -652,7 +652,7 @@
 ;; :object-node

 ;; XXX shouldn't be sent:
- ;; :text
+;; :text

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -761,7 +761,7 @@

 ;; (comment
 ;;   (session->map (create-session {:uri "xdbc://localhost:8383/"
-;;                                     :user "rest-admin" :password "x"
+;;                                     :user "test-admin" :password "uruktesting"
 ;;                                     :content-base "TutorialDB"}
 ;;                                    {} (uri-content-source "xdbc://localhost:8383/"
 ;;                                                           (security-options TODO)))))
@@ -792,7 +792,7 @@
 (deftest content-source-creation-with-host-port-user-pwd
   (testing "content source creation from host and port"
     (let [cs (make-hosted-content-source "localhost" 8383
-                                         {:user "rest-admin" :password "x"})]
+                                         {:user "test-admin" :password "uruktesting"})]
       (and (instance? ContentSource cs)
            (= 8383 (.getPort (.getConnectionProvider cs)))
            (= "localhost" (.getHostName (.getConnectionProvider cs)))))))
@@ -800,18 +800,18 @@
 ;; TODO with SSLContext
 ;; (comment
 ;;   (describe-session-options (create-session {:uri "xdbc://localhost:8383/"
-;;                                     :user "rest-admin" :password "x"
+;;                                     :user "test-admin" :password "uruktesting"
 ;;                                     :content-base "TutorialDB"}
 ;;                                    (hosted-content-source "localhost" 8383
-;;                                                           "rest-admin" "x" "TutorialDB"
+;;                                                           "test-admin" "x" "TutorialDB"
 ;;                                                           (security-options TODO))
 ;;                                    {}))

 ;;   (describe-session-options (create-session {:uri "xdbc://localhost:8383/"
-;;                                     :user "rest-admin" :password "x"
+;;                                     :user "test-admin" :password "uruktesting"
 ;;                                     :content-base "TutorialDB"}
 ;;                                    (managed-content-source connection-provider ;; TODO implement https://docs.marklogic.com/javadoc/xcc/com/marklogic/xcc/spi/ConnectionProvider.html interface
-;;                                                            "rest-admin" "x" "TutorialDB")
+;;                                                            "test-admin" "x" "TutorialDB")
 ;;                                    {})))

 (deftest content-src-options
@@ -1038,7 +1038,7 @@
         (is (= "binary()"
                (result->type (with-open [session (create-session db)]
                                (execute-xquery session (str "xquery version \"1.0-ml\";
-                                                       xdmp:external-binary(\""
+                                                             xdmp:external-binary(\""
                                                             path-to-img "\");")
                                                {:types :raw})))))
         (is (= (Class/forName "[B")
@@ -1052,22 +1052,25 @@
     (testing "......XSAnyURI"
       (with-open [session (create-session db)]
         (is (= "xs:anyURI"
-               (result->type (execute-xquery session "fn:resolve-uri(\"hello/goodbye.xml\", \"http://mycompany/default.xqy\")"
+               (result->type (execute-xquery session "fn:resolve-uri(\"hello/goodbye.xml\",
+                                                                     \"http://mycompany/default.xqy\")"
                                              {:types :raw})))))

       (with-open [session (create-session db)]
         (is (= "http://mycompany/hello/goodbye.xml"
                (execute-xquery session "fn:resolve-uri(\"hello/goodbye.xml\",
-                                                 \"http://mycompany/default.xqy\")"
+                                                       \"http://mycompany/default.xqy\")"
                                {:shape :single!})))))

     (testing "......XSBase64Binary"
       (is (= "xs:base64Binary"
              (result->type (with-open [session (create-session db)]
-                             (execute-xquery session "xs:base64Binary(\"bmhnY2p2\")" {:types :raw})))))
+                             (execute-xquery session "xs:base64Binary(\"bmhnY2p2\")"
+                                             {:types :raw})))))
       (is (= (Class/forName "[B")
              (.getClass (with-open [session (create-session db)]
-                          (execute-xquery session "xs:base64Binary(\"bmhnY2p2\")" {:shape :single!}))))))
+                          (execute-xquery session "xs:base64Binary(\"bmhnY2p2\")"
+                                          {:shape :single!}))))))

     (testing "......XSBoolean"
       (with-open [session (create-session db)]
@@ -1076,9 +1079,9 @@
                                              {:types :raw}))))
         (is (false? (execute-xquery session "fn:doc-available(\"derp\")" {:shape :single!})))
         (is (= "xs:boolean"
-               (result->type (execute-xquery session "xdmp:exists(collection())"
+               (result->type (execute-xquery session "fn:true()"
                                              {:types :raw}))))
-        (is (true? (execute-xquery session "xdmp:exists(collection())" {:shape :single!})))))
+        (is (true? (execute-xquery session "fn:true()" {:shape :single!})))))

     (testing "......XSDate"
       (with-open [session (create-session db)]


Default to not run network tests

Default to not run network tests

--- test/comic_reader/sites_test.clj
+++ test/comic_reader/sites_test.clj
@@ -221,7 +221,7 @@
     (catch java.net.UnknownHostException e
       false)))

-(defonce run-network-tests? (atom true))
+(defonce run-network-tests? (atom false))

 (defn try-fetch-url [url]
   (some-> url


test for CLJS-921

test for CLJS-921

--- test/cljs/cljs/core_test.cljs
+++ test/cljs/cljs/core_test.cljs
@@ -2531,6 +2531,10 @@
             (is (= s (set (remove #(zero? (mod % 3)) (range 100))))))))))
 )

+(deftest test-921-var-meta-name
+  (testing "testing CLJS-921, :name var metadata should be unqualified"
+    (is (= (-> (var first) meta :name) 'first))))
+
 (comment
   ;; ObjMap
   ;; (let [ks (map (partial str "foo") (range 500))


test for CLJS-920

test for CLJS-920

--- test/cljs/cljs/core_test.cljs
+++ test/cljs/cljs/core_test.cljs
@@ -2535,6 +2535,18 @@
   (testing "testing CLJS-921, :name var metadata should be unqualified"
     (is (= (-> (var first) meta :name) 'first))))

+(deftype MyWatchable []
+  IWatchable
+  (-notify-watches [this oldval newval])
+  (-add-watch [this key f])
+  (-remove-watch [this key]))
+
+(deftest test-920-watch-ops-return-ref
+  (testing "tesing CLJS-92, add-watch/return-watch should return reference"
+    (let [w (MyWatchable.)]
+      (is (identical? (add-watch w :foo (fn [])) w))
+      (is (identical? (remove-watch w :foo) w)))))
+
 (comment
   ;; ObjMap
   ;; (let [ks (map (partial str "foo") (range 500))


No need for revoke delay.

No need for revoke delay.

--- test/onyx/hornetq/vm_test.clj
+++ test/onyx/hornetq/vm_test.clj
@@ -76,8 +76,7 @@
    :zookeeper/address "127.0.0.1:2185"
    :zookeeper/server? true
    :zookeeper.server/port 2185
-   :onyx/id id
-   :onyx.coordinator/revoke-delay 5000})
+   :onyx/id id})

 (def peer-config
   {:hornetq/mode :vm


Deduplicate usage of call-with-options

Deduplicate usage of call-with-options

--- test/comic_reader/sites_test.clj
+++ test/comic_reader/sites_test.clj
@@ -175,18 +175,17 @@
      (is
       (binding [~'site-name ~site-name]
         (expect-opts-are-map ~site-name)
-        (if (has-test-folder?)
-          (call-with-options
-           ((get-sites) site-name)
-           #(and
-             (test-image-page-extraction)
-             (test-extract-chapters-list)
-             (test-extract-comic-list)))
-          (error-must-have-test-data))
-        (when (connected-to-network?)
-          (call-with-options
-           ((get-sites) site-name)
-           #(test-scrape-urls)))
+        (call-with-options
+         ((get-sites) site-name)
+         #(and
+           (if (has-test-folder?)
+             (and
+              (test-image-page-extraction)
+              (test-extract-chapters-list)
+              (test-extract-comic-list))
+             (error-must-have-test-data))
+           (when (connected-to-network?)
+             (test-scrape-urls))))
         true))))

 (defmacro defsite-tests []


Fix small typo

Fix small typo

--- test/rum/test/server_render.cljc
+++ test/rum/test/server_render.cljc
@@ -123,7 +123,7 @@
             {:background-image "url('123')" ;; should escape quotes
              :fontWeight       10      ;; should convert from react-style properties to CSS
              "WebkitFlex"      1       ;; prefixed react-style prop
-             "msFlex"          1       ;; prefixed react-style prop (lowecase ms)
+             "msFlex"          1       ;; prefixed react-style prop (lowercase ms)
              "zIndex"          1}}]]) ;; accept strings too


Re-worked remote auth service errors to bubble up to the response.

--- dev-resources/src/cmr/opendap/dev.clj
+++ dev-resources/src/cmr/opendap/dev.clj
@@ -2,6 +2,7 @@
   "CMR OPeNDAP development namespace."
   (:require
     [cheshire.core :as json]
+    [clojure.data.xml :as xml]
     [clojure.java.io :as io]
     [clojure.pprint :refer [pprint]]
     [clojure.set :as set]
@@ -14,7 +15,8 @@
     [cmr.opendap.components.core]
     [com.stuartsierra.component :as component]
     [org.httpkit.client :as httpc]
-    [trifl.java :refer [show-methods]])
+    [trifl.java :refer [show-methods]]
+    [xml-in.core :as xml-in])
   (:import
     (java.net URI)
     (java.nio.file Paths)))


Add tests related to validation in an async pipeline

--- spec/rook/validation_spec.clj
+++ spec/rook/validation_spec.clj
@@ -6,6 +6,7 @@
     io.aviso.rook
     io.aviso.rook.schema-validation)
   (:require
+    [clojure.core.async :refer [<!!]]
     [schema.core :as s]
     [clojure.tools.logging :as l]
     [io.aviso.rook.async :as async]))
@@ -32,6 +33,13 @@
           (should= HttpServletResponse/SC_BAD_REQUEST (:status response))
           (should= "validation-error" (-> response :body :error))))

+    (it "should handle s/enum schema types"
+        ;; Test is necessary because the s/enum type, EnumSchema, is also IPersistentMap
+        ;; with key :vs which causes a failure treating the string (or keyword) from the data as
+        ;; a map as well.
+        (should-be-nil
+          (validate-against-schema {:params {:enable "true"}} {:enable (s/enum "true" "false")})))
+
     (it "ignores extra keys"
         (should-be-nil
           (validate-against-schema {:params {:name "Rook" :ssn "999-99-9999"}} example-schema))))
@@ -44,8 +52,32 @@
           (should= HttpServletResponse/SC_BAD_REQUEST
                    (->
                      (request :post "/")
-                     (assoc :data {:first-name "Wrong Key"})
+                     (assoc :params {:first-name "Wrong Key"})
                      handler
+                     :status)))))
+
+  (describe "async middleware"
+
+    (let [handler (async/namespace-handler 'validating)]
+      (it "is present in the default async pipeline"
+          (should= HttpServletResponse/SC_BAD_REQUEST
+                   (->
+                     (request :post "/")
+                     (assoc :params {:first-name "Wrong Key"})
+                     handler
+                     <!!
+                     :status)))
+
+      (it "does not interfere with valid request"
+
+          (should= HttpServletResponse/SC_OK
+                   (->
+                     (request :post "/")
+                     (assoc :params {:name "Provided"})
+                     handler
+                     <!!
                      :status))))))

+
+
 (run-specs)


Parameterise a real time session

Parameterise a real time session

This is so that we can have multiple sessions on the same web page

--- src/webapp/framework/client/main.cljs
+++ src/webapp/framework/client/main.cljs
@@ -81,15 +81,11 @@

-(defn main []
+
+
+(defn load-vm [cookie-name    cookie-session-id    view-window     dom-element]
   (go
-    (reset-app-state)
-    (@init-fn)
-    (detect-browser)
-    ;(js/alert (str "cookie name:" (get-cookie-name)))
-
-    (let [cookie-session-id              (cookie/get  (get-cookie-name))
-          create-session-response        (remote !create-session {
+    (let [create-session-response        (remote !create-session {
                                                                    :init-state (with-out-str (prn @app-state))

                                                                    :browser    (str (-> @app-state :system :platform) ","
@@ -100,19 +96,39 @@
       (log (str "cookie-session-id: " cookie-session-id))
       (log (str "create-session-response: " create-session-response))

+      (reset-app-state)
+      (@init-fn)
+      (detect-browser)
+      ;(js/alert (str "cookie name:" (get-cookie-name)))
+
+
+
       (reset! client-session-atom  {:session-id   (:session-id create-session-response)
                                     :user         (:user create-session-response)})
       (swap! client-sessions assoc (:session-id create-session-response) (atom {}))

       ;(js/alert (str "Retrieved session ID : " cookie-session-id))

-      (cookie/set  (get-cookie-name)  (:session-id create-session-response)))
+      (cookie/set  cookie-name  (:session-id create-session-response))
+
+      (om/root   view-window
+                 app-state
+
+                 {:target dom-element}))))

-    (om/root   main-view
-               app-state

-               {:target (. js/document (getElementById "main"))})))
+
+
+
+
+
+(defn main []
+
+  (load-vm  (get-cookie-name)
+            (cookie/get  (get-cookie-name))
+            main-view
+            (. js/document (getElementById "main"))))


eval delays

eval delays


Rename domain to ws-host, move ws-host into arg map, and replace double if with cond

--- src/adzerk/boot_reload.clj
+++ src/adzerk/boot_reload.clj
@@ -4,7 +4,6 @@
    [boot.core          :as b]
    [clojure.java.io    :as io]
    [clojure.set        :as set]
-   [clojure.string     :as string]
    [boot.pod           :as pod]
    [boot.file          :as file]
    [boot.util          :as util]
@@ -23,10 +22,11 @@
          (sort-by :dependency-order)
          (map tmp-path))))

-(defn- start-server [pod {:keys [ip port] :as opts} domain]
+(defn- start-server [pod {:keys [ip port ws-host] :as opts}]
   (let [{:keys [ip port]}
         (pod/with-call-in pod (adzerk.boot-reload.server/start ~opts))
-        host (if-not (string/blank? domain) domain (if-not (= ip "0.0.0.0") ip "localhost"))]
+        host
+        (cond ws-host ws-host (= ip "0.0.0.0") "localhost" :else ip)]
     (util/with-let [url (format "ws://%s:%d" host port)]
       (util/info "<< started reload server on %s >>\n" url))))

@@ -77,7 +77,7 @@
   [b ids BUILD_IDS #{str} "Only inject reloading into these builds (= .cljs.edn files)"
    i ip ADDR         str  "The (optional) IP address for the websocket server to listen on."
    p port PORT       int  "The (optional) port the websocket server listens on."
-   d domain DOMAIN   str  "The (optional) server domain name to pass through requests."
+   w ws-host WSADDR  str  "The (optional) websocket host address to pass to clients."
    j on-jsload SYM   sym  "The (optional) callback to call when JS files are reloaded."
    a asset-path PATH str  "The (optional) asset-path. This is removed from the start of reloaded urls."]

@@ -86,7 +86,7 @@
         tmp  (tmp-dir!)
         prev (atom nil)
         out  (doto (io/file src "adzerk" "boot_reload.cljs") io/make-parents)
-        url  (start-server @pod {:ip ip :port port} domain)]
+        url  (start-server @pod {:ip ip :port port :ws-host ws-host})]
     (set-env! :source-paths #(conj % (.getPath src)))
     (write-cljs! out url on-jsload)
     (comp


Change backtick require to use alias for 2.6 compatibility

Refer caused a clash because template is refered both from boot.core and
backtick.

--- src/adzerk/boot_reload.clj
+++ src/adzerk/boot_reload.clj
@@ -8,7 +8,7 @@
    [boot.file          :as file]
    [boot.util          :as util]
    [boot.core          :refer :all]
-   [boot.from.backtick :refer [template]]))
+   [boot.from.backtick :as bt]))

 (def ^:private deps '[[http-kit "2.1.18"]])

@@ -33,7 +33,7 @@
 (defn- write-cljs! [f url ws-host on-jsload asset-host]
   (util/info "Writing %s to connect to %s...\n" (.getName f)
              (if ws-host url "default websocket host"))
-  (->> (template
+  (->> (bt/template
          ((ns adzerk.boot-reload
             (:require
              [adzerk.boot-reload.client :as client]


[#8239] App crash when submit cryptokitties with different than it's valid domain

Signed-off-by: Andrey Shovkoplyas <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/ui/screens/browser/site_blocked/views.cljs
+++ src/status_im/ui/screens/browser/site_blocked/views.cljs
@@ -8,11 +8,6 @@
             [status-im.ui.screens.browser.site-blocked.styles :as styles])
   (:require-macros [status-im.utils.views :as views]))

-(defn chat-link []
-  [react/text {:on-press #(.openURL react/linking "status-im://chat/public/status")
-               :style    styles/chat-link-text}
-   "#status"])
-
 (views/defview view [{:keys [can-go-back?]}]
   [react/scroll-view {:keyboard-should-persist-taps :always
                       :bounces                      false
@@ -21,10 +16,12 @@
     [vector-icons/icon :main-icons/info {:color colors/red}]
     [react/text {:style styles/title-text}
      (i18n/label :t/browsing-site-blocked-title)]
-    [react/text {:style styles/description-text}
+    [react/nested-text  {:style styles/description-text}
      (i18n/label :t/browsing-site-blocked-description1)
-     [chat-link]
-     [react/text (i18n/label :t/browsing-site-blocked-description2)]]
+     [{:on-press #(.openURL react/linking "status-im://chat/public/status")
+       :style    styles/chat-link-text}
+      "#status"]
+     (i18n/label :t/browsing-site-blocked-description2)]
     [react/view styles/buttons-container
      [components.common/button {:on-press (fn []
                                             (let [handler (if can-go-back?


deleting unused deps

deleting unused deps

--- support/src/figwheel/client/utils.clj
+++ support/src/figwheel/client/utils.clj
@@ -1,7 +1,4 @@
-(ns figwheel.client.utils
-  (:require [cljs.analyzer.api :as api]
-            [cljs.compiler]
-            [clojure.walk :as walk]))
+(ns figwheel.client.utils)

 (def dev-blocks? (atom false))


Add spyscope dependency.

Add spyscope dependency.

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -1,4 +1,5 @@
-{:user {:dependencies [[clj-stacktrace "0.2.4"]]
+{:user {:dependencies [[clj-stacktrace "0.2.4"]
+                       [spyscope "0.1.0"]]
         :plugins [[lein-tarsier "0.9.4-SNAPSHOT"]
                   [lein-swank "1.4.4"]
                   [lein-difftest "1.3.7"]


add dashboard route

add dashboard route

--- src-cljs/frontend/routes.cljs
+++ src-cljs/frontend/routes.cljs
@@ -225,6 +225,9 @@
       (open-to-inner! nav-ch :dashboard params)
       (open-to-outer! nav-ch :landing (assoc params :_canonical "/"))))

+  (defroute v1-dashboard "/dashboard" {:as params}
+    (open-to-inner! nav-ch :dashboard params))
+
   (defroute v1-home "/home" {:as params}
     (open-to-outer! nav-ch :landing (assoc params :_canonical "/")))


ugh i dunno

ugh i dunno

--- src-cljs/views/head-form.cljs
+++ src-cljs/views/head-form.cljs
@@ -9,10 +9,11 @@
 (def form-data (atom {}))
 (def csrf-token (atom ""))
 (def existing-heads (atom []))
+(def errors (atom []))

 (defn- name-taken?
-  [name heads]
-  (in? name (map :name heads)))
+  [head-name heads]
+  (in? head-name (map :name heads)))

 (defn- submit-form
   [submit-url]
@@ -24,8 +25,6 @@
         (if (http-ok? (:status response))
           (redirect-to (:success-url response))
           (show-form-error (:error response)))))))
-
-(enable-console-print!)

 (defn- name-invalid?
   [head-name]


Minor updates/fixes.

Minor updates/fixes.

--- dev-resources/src/dragon/dev.clj
+++ dev-resources/src/dragon/dev.clj
@@ -18,8 +18,6 @@
             [dragon.components.system :as components]
             [dragon.main :as main]
             [dragon.util :as util]
-            [dragon.web.core :as web]
-            [dragon.web.content :as content]
             [markdown.core :as md]
             [selmer.parser :as selmer]
             [taoensso.timbre :as log]
@@ -45,13 +43,13 @@
       (log/error "System has aready been initialized.")
       (do
         (alter-var-root #'system
-          (constantly ((components/init mode)))
+          (constantly ((components/init mode))))
         (alter-var-root #'state (fn [_] :initialized))))
     state))

 (defn deinit
   []
-  (if (contains? [] state)
+  (if (contains? invalid-deinit-transitions state)
     (log/error "System is not stopped; please stop before deinitializing.")
     (do
       (alter-var-root #'system (fn [_] nil))
@@ -60,7 +58,7 @@

 (defn start
   ([]
-    (start :repl))
+    (start :default))
   ([mode]
     (when (nil? system)
       (init mode))


Produce public keys in miniwallet generator #280

--- src/bitcoin/miniwallet.clj
+++ src/bitcoin/miniwallet.clj
@@ -5,8 +5,11 @@
   (:require [clojure.string :as str]
             [pandect.algo.sha256 :refer :all]))

-(defn address [k]
-  (Address. (NetworkParameters/prodNet) (.getPubKeyHash k)))
+(defn private-to-address [k]
+  (.toString (Address. (NetworkParameters/prodNet) (.getPubKeyHash k))))
+
+(defn private-to-pubkey-string [k]
+  (format "%0130x" (java.math.BigInteger. (.getPubKey k))))

 (defn gen-key []
   ;; hack to get the key uncompressed, because bitcoinj makes it compressed by default.
@@ -25,13 +28,13 @@
          testkey
       (recur (minikey-candidate)))))

-(defn minikey-to-address [minikey]
-  (.toString (address (ECKey/fromPrivate (BigInteger. (sha256 minikey) 16) false))))
+(defn minikey-to-private [minikey]
+  (ECKey/fromPrivate (BigInteger. (sha256 minikey) 16) false))

 (defn gen-miniwallet []
   (let [key-str (gen-minikey)
-        add-str (minikey-to-address key-str)]
-    (println add-str key-str)))
+        key (minikey-to-private key-str)]
+    (println key-str (private-to-pubkey-string key) (private-to-address key))))

 (defn -main [& args]
   (doseq [x (range (bigint (first args)))] (gen-miniwallet)))


Fix random block content in store tests.

--- src/blocks/store/tests.clj
+++ src/blocks/store/tests.clj
@@ -16,7 +16,7 @@
   "Stores some test blocks in the given block store and returns a map of the
   ids to the original content values."
   [store n max-size]
-  (->> (repeatedly #(util/random-bytes max-size))
+  (->> (repeatedly #(util/random-bytes (inc (rand-int max-size))))
        (take n)
        (map (juxt (comp :id (partial block/store! store)) identity))
        (into (sorted-map))))


Define the line-height on the toc

Define the line-height on the toc

not on the individual entry

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -86,7 +86,7 @@

 (defn- sub-toc-entry [items fmt genre]
   (when-let [items (genre items)]
-    [:fo:block {:line-height "150%"}
+    [:fo:block
      [:fo:block {:text-align-last "justify"}
       [:fo:basic-link {:internal-destination (hash [fmt genre])}
        (str (layout/translations genre) " ")
@@ -95,7 +95,7 @@
      (keep #(sub-sub-toc-entry items fmt genre %) layout/subgenres)]))

 (defn sub-toc [items fmt]
-  [:fo:block
+  [:fo:block {:line-height "150%"}
    (keep #(sub-toc-entry items fmt %)
          (if (= fmt :braille) layout/braille-genres layout/genres))])


Layout tweak

Layout tweak

For each issue the number of the issue is not completely centered within
the circle. Add a map where an offset can be specified for each issue.

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -448,6 +448,14 @@
    (issue-colors col)
    (map #(/ % 100.0))
    rgb))
+
+(def issue-indent
+  "Mapping of indents for each issue."
+  ;; In theory the issue numbers should be centered properly within the
+  ;; circle. Somehow this doesn't seem to pan out, so we resort to
+  ;; fidget with the indent for each issue.
+  {3 "143mm"
+   4 "140mm"})

 (defn- coverpage-recto [title year issue]
   (let [fill-color (format "fill:%s device-%s" (color-rgb issue) (color issue))]
@@ -508,7 +516,7 @@
                :role "H2"}
               (layout/format-date year issue))]
       [:fo:block-container {:absolute-position "fixed" :width "53mm" :height "53mm"
-                            :left "143mm" :top "119mm" :display-align "center"
+                            :left (issue-indent issue "140mm") :top "119mm" :display-align "center"
                             :background-color "transparent"}
        (block {:font-size "120pt" :color (color :white)
                :text-align "center"


Cleaned up import prior to pull request

Cleaned up import prior to pull request

--- test/reimann/test/core.clj
+++ test/reimann/test/core.clj
@@ -6,7 +6,6 @@
   (:use [reimann.core])
   (:use reimann.index)
   (:use [clojure.algo.generic.functor :only (fmap)])
-  ;(:use [clojure.contrib.generic.functor :only (fmap)])
   (:use [clojure.test]))

 (defmacro tim


simpler reverse compare

simpler reverse compare

--- sample/src/sample/core.clj
+++ sample/src/sample/core.clj
@@ -54,7 +54,7 @@
                                      (fn [tmap]
                                        (if tmap
                                          (assoc tmap t v)
-                                         (sorted-map-by #(* -1 (compare %1 %2)) t v)))))
+                                         (sorted-map-by #(compare %2 %1) t v)))))
                         {}
                         lres))))]


Add correct source path in order to include in jar

--- dfs-datastores/project.clj
+++ dfs-datastores/project.clj
@@ -26,6 +26,7 @@
                  [:developer
                   [:name "Sam Ritchie"]
                   [:url "http://twitter.com/sritchie"]]]
+  :source-paths ["src/main/java"]
   :javac-options ["-source" "1.6" "-target" "1.6"]
   :java-source-paths ["src/main/java" "src/test/java"]
   :junit ["src/test/java"]


Use json-verbose transit encoding in dev mode

--- src/clj/cglossa/server.clj
+++ src/clj/cglossa/server.clj
@@ -29,7 +29,7 @@

 (defn- transit-response* [body]
   (let [baos   (ByteArrayOutputStream. 2000)
-        writer (transit/writer baos :json)
+        writer (transit/writer baos (if (:is-dev env) :json-verbose :json))
         _      (transit/write writer body)
         res    (.toString baos)]
     (.reset baos)


implement Archangel and Special Offer

implement Archangel and Special Offer

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -5,7 +5,16 @@
 (def end-the-run {:msg "end the run" :effect (effect (end-run))})

 (def cards-ice
-  {"Archer"
+  {"Archangel"
+   {:access {:optional
+             {:prompt "Pay 3 [Credits] to force Runner to encounter Archangel?" :cost [:credit 3]
+              :effect (req (system-msg state :corp "pays 3 [Credits] to force the Runner to encounter Archangel"))}}
+    :abilities [{:label "Trace 6 - Add 1 installed card to the Runner's Grip"
+                 :trace {:base 6 :choices {:req #(:installed %)}
+                         :msg (msg "add " (:title target) " to the Runner's Grip")
+                         :effect (effect (move :runner target :hand true))}}]}
+
+   "Archer"
    {:additional-cost [:forfeit]
     :abilities [{:msg "gain 2 [Credits]" :effect (effect (gain :credit 2))}
                 trash-program end-the-run]}
@@ -528,6 +537,11 @@
    {:abilities [{:msg "start a Psi game"
                  :psi {:not-equal end-the-run}}]}

+   "Special Offer"
+   {:abilities [{:label "Gain 5 [Credits] and trash Special Offer"
+                 :effect (effect (gain :corp :credit 5) (trash card)
+                                 (system-msg (str "gains 5 [Credits] and trashes Special Offer")))}]}
+
    "Spiderweb"
    {:abilities [end-the-run]}


First x86 implemtation: default rule for Move

--- src/clj/minijava/munch.clj
+++ src/clj/minijava/munch.clj
@@ -6,6 +6,9 @@
 (= (type x) t)
 )

+(defn emit [x]
+
+)

 ;;ir is the root of the ir tree to munch; args is an (optional) list of the 'children' of the root node, for pattern matching purposes.
 ;;its ok to omit args.
@@ -20,7 +23,6 @@
 ;;This method contains a bunch of special cases, organized by preference (size), of x86 statements that can
 ;;do a Move on a Mem and then (any) expression.
 ;;Similar methods can be defined for a Move and any combination of its arguments, all the way up to Move (Expression Expression)
-;;Note that src and dst are swapped in order relative to the book.
 (defmethod munch :minijava.ir/Move :minijava.ir/Expression :minijava.ir/Mem
   [x src dst]
   (cond
@@ -29,9 +31,27 @@
   	(and (isit? (:adr dst) :minijava.ir/BinaryOp) (= (:op (:adr dst)) :+)  (isit? (:exp1 (:adr dst)) :minijava.ir/Const))
   						(do (munch (:exp2 (:adr dst)));;Here, we need to muncn e1 and e2 in the statement above: that is, the non-const argument to Binop, and the Expression for Move.
   								(munch src)
-  								 :STORE) ;;AFTER munching these two statements, return the result of this statement.
+  								 (emit :STORE)) ;;AFTER munching these two statements, return the result of this statement.

   ))
+
+
+  ;;Default Move pattern: just use Movl
+  (defmethod munch :minijava.ir/Move :minijava.ir/Expression :minijava.ir/Expression
+  [x src dst]
+  	;;Move(e1,e2) -> Movl e1 e2
+  	  (do (munch src)
+  				(munch dst)
+  				 (emit :movl))) ;;AFTER munching these two statements, return the result of this statement.
+
+  ;;Default Mem pattern: as far as I can tell, you cannot have a Mem statement by itself in x86 - it has no destination.
+  ;;So we'll invent a new temp, and move the memory location into that temp?
+  (defmethod munch :minijava.ir/Mem :minijava.ir/Expression
+  [x src dst]
+  	;;Mem(addr) -> Movl [adr] e2
+  	  (do (munch src)
+  				(munch dst)
+  				 (emit :movl))) ;;AFTER munching these two statements, return the result of this statement.


Minor formatting change.

Minor formatting change.

--- src/clj_ravendb/client.clj
+++ src/clj_ravendb/client.clj
@@ -198,7 +198,7 @@
   ([client watch-fn channel]
    (watch client watch-fn channel {}))
   ([client watch-fn channel {:keys [wait]
-                          :or {wait 500}}]
+                             :or {wait 500}}]
    (let [keep-watching? (atom true)
          f (future
              (println "Watching" watch "for changes")


Fetching repositories for given user works

Though data isn't used yet anything

--- src/cljs/repodoc/core.cljs
+++ src/cljs/repodoc/core.cljs
@@ -5,7 +5,7 @@
     [m]
     [goog.i18n.DateTimeFormat :as dtf]
     [repodoc.data :refer [REPO FILETYPES]]
-    [repodoc.fathom :refer [nm]]
+    [repodoc.fathom :refer [nm request]]
     [repodoc.utils :refer [serialize-md serialize-edn serialize-html serialize format_time]]
     [repodoc.editor :as e]
     [devtools.core :as devtools]
@@ -209,7 +209,8 @@

 (defn fetch_repositories
   [db username]
-  (let [repourl (str "https://api.github.com/users/" username "/repos/")]))
+  (let [repourl (str "https://api.github.com/users/" username "/repos")]
+    (request {:url repourl}  #(println %))))

 (defn index_view
   [{:keys [username repositories]} ctrl]
@@ -219,8 +220,10 @@
                  [(nm "input"
                       {"placeholder" "Github username"
                        "value" username
-                       :onchange (e/text "username" username 40 #(fetch_repositories ctrl %))})
-                  (nm "div" "")])]))
+                       :onchange (e/text "username" username 40 #())})
+                  (nm "div" [
+                             (nm "button" {:onclick #(fetch_repositories ctrl username)} "Fetch")
+                             ])])]))

 ;; Setup


add atom-input || remove unusued 'completed' class

--- src/cljs/todomvc/core.cljs
+++ src/cljs/todomvc/core.cljs
@@ -67,8 +67,7 @@
 (defn todo-entry []
   (let [editing (atom false)]
     (fn [{:keys [id text done]}]
-      [:li {:class (str (if done "completed ")
-                        (if @editing "editing"))}
+      [:li {:class (if @editing "editing")}
        (let [checkbox-id (str "check" id)]
          [:div
           [:input {:type "checkbox"
@@ -82,14 +81,24 @@
                       :on-save #(do (save! id %)
                                     (reset! editing false))}])])))

+(defn atom-input
+  ([value] (atom-input value nil))
+  ([value props]
+   [:input (merge
+            {:type "text"
+             :value @value
+             :on-change #(reset! value (-> % .-target .-value))}
+            props)]))
+
+
 (defn new-todo []
   (let [todo (atom "")]
     (reagent/create-class {:render
                            (fn []
                               [:input#new-todo
                                {:type "text"
+                                :value @todo
                                 :placeholder "What needs to be done?"
-                                :value @todo
                                 :on-change #(reset! todo (.. % -target -value))
                                 :on-key-down #(case (.-which %)
                                                 13 ((fn [_] (if-not (empty? (-> @todo str clojure.string/trim))


add type parsing

add type parsing

--- src/cljs_api_gen/parse.clj
+++ src/cljs_api_gen/parse.clj
@@ -172,9 +172,12 @@

 (defn parse-deftype
   [form]
-  #_{:docstring docstring
-     :signature [signature]
-     :type "type"})
+  (let [name- (second form)
+        form (drop 2 form)
+        signature (first form)]
+  {:docstring nil
+   :signature [signature]
+   :type "type"}))

 (defmulti parse-form*
   (fn [form]


manually insert emoji images until github allows it for large markdown docs

--- src/cljs_api_gen/write.clj
+++ src/cljs_api_gen/write.clj
@@ -53,6 +53,20 @@
   (-> s
       (replace "-" "--")
       ))
+
+(def emoji-url
+  "emoji table here: http://apps.timwhitlock.info/emoji/tables/unicode"
+  {":heavy_check_mark:" "http://i.imgur.com/JfULGnn.png"
+   ":no_entry_sign:"    "http://i.imgur.com/sWBgjc6.png"})
+
+(defn fix-emoji
+  "github currently disables emoji-rendering for large readmes, so just process them here."
+  [s]
+  (reduce
+    (fn [s emoji]
+      (replace s emoji
+        (str "<img width=\"20px\" height=\"20px\" valign=\"middle\" src=\"" (emoji-url emoji) "\">")))
+    s (keys emoji-url)))

 ;;--------------------------------------------------------------------------------
 ;; Common
@@ -191,10 +205,10 @@

 (defn dump-history! [result]
   (spit (str *output-dir* "/HISTORY.md")
-        (stencil/render-string
+        (fix-emoji (stencil/render-string
           (slurp "templates/history.md")
           (history-file-data result)
-          )))
+          ))))

 ;;--------------------------------------------------------------------------------
 ;; unported file
@@ -222,9 +236,9 @@

 (defn dump-unported! [result]
   (spit (str *output-dir* "/UNPORTED.md")
-        (stencil/render-string
+        (fix-emoji (stencil/render-string
           (slurp "templates/unported.md")
-          (unported-file-data result))))
+          (unported-file-data result)))))

 ;;--------------------------------------------------------------------------------
 ;; readme file
@@ -275,10 +289,10 @@

 (defn dump-readme! [result]
   (spit (str *output-dir* "/README.md")
-        (stencil/render-string
+        (fix-emoji (stencil/render-string
           (slurp "templates/readme.md")
           (readme-file-data result)
-          )))
+          ))))

 ;;--------------------------------------------------------------------------------
 ;; Main


Remove debugging.

Remove debugging.

--- modules/core/src/main/clojure/immutant/runtime/bootstrap.clj
+++ modules/core/src/main/clojure/immutant/runtime/bootstrap.clj
@@ -87,11 +87,9 @@
 (defn ^{:internal true} resource-paths
   "Resolves the resource paths (in the AS7 usage of the term) for an application."
   [app-root]
-  (let [foo (if-let [project (read-project app-root)]
-              (resource-paths-from-project project)
-              (resource-paths-for-projectless-app app-root))]
-    (println foo)
-    foo))
+  (if-let [project (read-project app-root)]
+    (resource-paths-from-project project)
+    (resource-paths-for-projectless-app app-root)))

 (defn ^{:internal true} bundled-jars
   "Returns a vector of any jars that are bundled in the application's lib-dir."


oops

oops

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@7231 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- sandbox/refs/src/refs/core.clj
+++ sandbox/refs/src/refs/core.clj
@@ -63,4 +63,4 @@
     para))

 (defn doi-to-pmcid [doi]
-  (-> doi pmid-to-pmcid doi-to-pmid doi))
+  (-> doi doi-to-pmid pmid-to-pmcid doi))


Remove explicit namespace qualifier

Remove explicit namespace qualifier

which does not help at all -- prxml seems to be broken with newest
clojure snapshot.

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/io/contexts.clj
+++ src/conexp/io/contexts.clj
@@ -195,7 +195,7 @@

         atts-vector (sort #(< (atts %1) (atts %2)) (attributes ctx))
         objs-vector (sort #(< (objs %1) (objs %2)) (objects ctx))]
-    (binding [clojure.contrib.prxml/*prxml-indent* 2]
+    (binding [*prxml-indent* 2]
       (with-out-writer file
         (prxml [:decl! {:vecsion "1.0"}])
         (prxml [:Galicia_Document


show the correct QR code for baskets that have just been loaded

--- src/eatme/client/main.cljs
+++ src/eatme/client/main.cljs
@@ -88,6 +88,8 @@

 (def completed-item (pubsub/publishize (fn [e] {:item e}) bus))

+(def basket-loaded (pubsub/publishize identity bus))
+
 (defn add-item-to-list [item]
   (when (and (< 0 (:qty item)) (not-empty (:item-name item)))
     (d/append! items-list (render/shopping-list-item item))
@@ -97,14 +99,16 @@
       (event/listen! (css/sel new-item "button[rel=decrement]") :click #(quantity-changed :dec true (event/target %)))
       (event/listen-once! (css/sel new-item "button[rel=complete]") :click #(completed-item (event/target %))))))

+(defn set-basket-contents! [basket]
+  (d/destroy-children! items-list)
+  (doseq [item (:items basket)]
+    (add-item-to-list item)))
+
 (defn load-basket []
   (when-let [basket-id (basket-id)]
     (srm/rpc
      (api/load-basket basket-id) [basket]
-     :on-success (do
-                   (d/destroy-children! items-list)
-                   (doseq [item (:items basket)]
-                     (add-item-to-list item)))
+     :on-success (basket-loaded basket)
      :on-error (js/alert (str "Error loading basket: " basket-id)))))

@@ -213,6 +217,11 @@
 (pubsub/subscribe bus basket-saved (fn [b] (history/set-token session-history (str (:id b)))))
 (pubsub/subscribe bus basket-saved display-qr-code)

+(pubsub/subscribe bus basket-loaded set-basket-contents!)
+(pubsub/subscribe bus basket-loaded display-qr-code)
+(pubsub/subscribe bus basket-loaded (partial log-to-console "Basket loaded"))
+
+
 (display-user-details)
 (load-basket)
 (focus-item-input)


added schema for fibo function

added schema for fibo function

--- src/egyptian_gods/core.clj
+++ src/egyptian_gods/core.clj
@@ -47,6 +47,9 @@
    :offspring s/Str
    :greek-equivalent s/Str})

+(s/defschema fibo-numbers
+  {:steps Long, :fibo-array [Long], :fibo-result Long})
+
 (defn mapify-gods
   [pdf]
   (map
@@ -87,12 +90,16 @@
       (GET "/time-lord" []
         :return String
         :summary "return local time"
-        (io/resource "public/index.html")
         (ok (timelord)))
+      (GET "/fibo" []
+        :return fibo-numbers
+        :query-params [steps :- Long]
+        :summary "return fibonacci numbers"
+        (ok (fibo steps)))
       (POST "/add-god" []
-        :return String
+        :return god
         :body [gods god]
-        (ok "I am a God"))))))
+        (ok gods))))))

 ;;Middleware is a function that receives the request and response objects of an HTTP request/response cycle.
 ;;in other frameworks “middleware” is called “filters”
@@ -108,7 +115,7 @@
       wrap-json-response
       wrap-multipart-params
       (wrap-cors :access-control-allow-origin [#"http://localhost:3000"]
-                  :access-control-allow-methods [:get :put :post :delete])))
+                 :access-control-allow-methods [:get :put :post :delete])))

 (defn -main []
   (run-server (app) {:port (:port @config)})


Update ioframes.clj

Update ioframes.clj

--- src/iyye/bios/ioframes.clj
+++ src/iyye/bios/ioframes.clj
@@ -26,7 +26,7 @@

 (defrecord IO [name start-function inputs-list outputs-list])

-(defn create-IO [name start-fumction inputs-list outputs-list] (IO. name start-fumction inputs-list outputs-list))
+(defn create-IO [name start-function inputs-list outputs-list] (IO. name start-function inputs-list outputs-list))

 (defn process-input [IO input]
   (log/info (str "in: " (:name IO) input))
@@ -37,4 +37,3 @@
   (log/info (str "out:" (:name IO) output))
   (dorun (map #(% IO output) (:outputs-list (:outputs-list IO))))
   (persistence/write-io-to-db @resource/num-days IO :output output))
-


another test

another test

--- dada2-core/src/test/clojure/org/dada2/test_join_model.clj
+++ dada2-core/src/test/clojure/org/dada2/test_join_model.clj
@@ -34,6 +34,12 @@
     state
     (permute (mapcat (fn [i] (map (fn [j] (conj i j)) head)) state) tail)))

+
+(deftest test-permute
+  (is (=
+       [[:a1 :b1 :c1] [:a1 :b2 :c1] [:a1 :b3 :c1] [:a2 :b1 :c1] [:a2 :b2 :c1] [:a2 :b3 :c1]]
+       (permute [[]] [[:a1 :a2][:b1 :b2 :b3][:c1]]))))
+
 ;;--------------------------------------------------------------------------------
 ;; this layer encapsulates access to lhs index

@@ -51,6 +57,13 @@
       (fn [lhs-index lhs-fk-key] (assoc-in lhs-index [(lhs-fk-key lhs) lhs-pk] lhs))
       (first indeces)
       lhs-fk-keys))))
+
+(deftest test-lhs-access
+  (let [before [[{}]]
+	after  [[{String {3 "xxx"}}]]]
+    (is (= after (lhs-assoc before count [type] "xxx")))
+    (is (= '("xxx") (lhses-get (first after) 0 String)))
+    ))

 ;;--------------------------------------------------------------------------------
 ;; this layer encapsulates access to rhs indeces
@@ -193,11 +206,6 @@
 (deftest test-join-abc
   (is (= (->ABC [:a1 :b1 :c1] [0 0 0] "b-data" "c-data")
 	 (join-abc (->A :a1 0 :b :c)(->B :b1 0 :b "b-data")(->C :c1 0 :c "c-data")))))
-
-(deftest test-permute
-  (is (=
-       [[:a1 :b1 :c1] [:a1 :b2 :c1] [:a1 :b3 :c1] [:a2 :b1 :c1] [:a2 :b2 :c1] [:a2 :b3 :c1]]
-       (permute [[]] [[:a1 :a2][:b1 :b2 :b3][:c1]]))))

 (deftest test-join-model
   (let [as (versioned-optimistic-map-model (str :as) :name :version >)


simplify and test rhs access functions

simplify and test rhs access functions

--- dada2-core/src/test/clojure/org/dada2/test_join_model.clj
+++ dada2-core/src/test/clojure/org/dada2/test_join_model.clj
@@ -61,15 +61,15 @@
   "return a lazy seq of seqs of rhses indexed by their respective fks"
   (map (fn [rhs-index lhs-fk-key] (vals (rhs-index (lhs-fk-key lhs)))) rhs-indeces lhs-fk-keys))

-(defn- rhs-assoc [old-indeces i rhs-pk-key fk rhs]
+(defn- rhs-assoc [indeces i rhs-pk-key fk rhs]
   "associate a new rhs with existing index"
-  (let [old-index (nth old-indeces i)
-	old-rhses (or (old-index fk) {})
-	new-rhses (assoc old-rhses (rhs-pk-key rhs) rhs)
-	new-index (assoc old-index fk new-rhses)
-	new-indeces (assoc old-indeces i new-index)]
-    new-indeces
-    ))
+  (assoc-in indeces [i fk (rhs-pk-key rhs)] rhs))
+
+(deftest test-rhs-access
+  (let [before [[] {}]
+	after  [[] {String {3 "xxx"}}]]
+    (is (= after (rhs-assoc before 1 count String "xxx")))
+    (is (= '(("xxx")) (rhses-get (rest after) [first] [String])))))

 ;;--------------------------------------------------------------------------------
 ;; this layer encapsulates access to both lhs and rhs at the same time...
@@ -319,6 +319,13 @@
 	   }
 	   (data joined-model)))

-    ;; what about amend-in/out ?
-    ;; what about delete ?
+    ;; TODO:
+    ;;  amend in/out
+    ;;  delete
+    ;;  batch operations
+    ;;  test listener receives correct events
+    ;;  test downstream model receives correct events
+    ;;  unjoined models...
+    ;;  move prod code out of this file
+    ;;  refactor and document
     ))


Transform params keys recursively in screen

--- apps/mobile/src/souptitle_mobile/shared/components/screen.cljs
+++ apps/mobile/src/souptitle_mobile/shared/components/screen.cljs
@@ -7,6 +7,16 @@

 (def ExScreen (r/adapt-react-class (js/require "./screen.js")))

+(defn check-value [func]
+  (fn [[key val]]
+    (if (map? val)
+      [(->camelCaseString key) (func val)]
+      [(->camelCaseString key) val])))
+
+(defn transform-params [params]
+  (into {}
+        (map params (check-value transform-params))))
+
 (defn screen [route-params children]
-  [ExScreen (transform-keys ->camelCaseString route-params)
+  [ExScreen (transform-keys route-params)
    children])


store normalized source maps in the compiler state

--- src/main/cljs/cljs/js.cljs
+++ src/main/cljs/cljs/js.cljs
@@ -122,7 +122,7 @@
                  :file file :sources-content [source]})]
      (when (:verbose opts) (debug-prn json))
      (swap! state assoc-in
-       [:source-maps name] (:source-map sm-data))
+       [:source-maps name] (sm/invert-reverse-map (:source-map sm-data)))
      (.append sb
        (str "\n//# sourceURL=" file
             "\n//# sourceMappingURL=data:application/json;base64,"


[#2925] Add data-groups support to map visualisation/aggregation

--- backend/src/akvo/lumen/lib/visualisation/maps.clj
+++ backend/src/akvo/lumen/lib/visualisation/maps.clj
@@ -2,6 +2,8 @@
   (:require [akvo.lumen.http.client :as http.client]
             [akvo.lumen.lib :as lib]
             [akvo.lumen.postgres.filter :as filter]
+            [akvo.lumen.lib.aggregation.commons :as aggregation]
+            [akvo.lumen.lib.env :as env]
             [akvo.lumen.lib.visualisation.map-config :as map-config]
             [akvo.lumen.lib.visualisation.map-metadata :as map-metadata]
             [akvo.lumen.lib.transformation.engine :as engine]
@@ -107,7 +109,10 @@
                                     (:datasetId current-layer))
                {:keys [table-name columns raster_table]} (if (= current-layer-type "raster")
                                                            (db.raster/raster-by-id tenant-conn {:id current-dataset-id})
-                                                           (db.dataset/dataset-by-id tenant-conn {:id current-dataset-id}))
+                                                           (if (-> (env/all tenant-conn) (get "data-groups"))
+                                                             (or (aggregation/table-name-and-columns-from-data-grops tenant-conn current-dataset-id)
+                                                                 (db.dataset/dataset-by-id tenant-conn {:id current-dataset-id}))
+                                                             (db.dataset/dataset-by-id tenant-conn {:id current-dataset-id})))
                current-where-clause (filter/sql-str (walk/keywordize-keys columns) (:filters current-layer))]
            (map-metadata/build tenant-conn
                                (or raster_table


util/s3.clj: use clojure.contrib.singleton for s3

--- src/org/altlaw/util/s3.clj
+++ src/org/altlaw/util/s3.clj
@@ -1,7 +1,8 @@
 (ns org.altlaw.util.s3
   (:require [org.altlaw.util.zip :as zip]
             [org.altlaw.util.context :as context]
-            [org.altlaw.util.log :as log])
+            [org.altlaw.util.log :as log]
+            [clojure.contrib.singleton :as sing])
   (:import (org.jets3t.service S3Service)
            (org.jets3t.service.impl.rest.httpclient RestS3Service)
            (org.jets3t.service.model S3Bucket S3Object)
@@ -19,20 +20,21 @@
                               " " (. e# getS3ErrorMessage)) e#)))))

 (def #^{:private true} get-s3
-     (memoize (fn []
-                (log/debug "Called get-s3 memoized fn")
-                (log/info "Using jets3t library version "
-                          S3Service/VERSION_NO__JETS3T_TOOLKIT)
-                (RestS3Service.
-                 (AWSCredentials. (context/aws-access-key-id)
-                                  (context/aws-secret-access-key))))))
+     (sing/per-thread-singleton
+      (fn []
+        (log/info "get-s3: Using jets3t library version "
+                  S3Service/VERSION_NO__JETS3T_TOOLKIT)
+        (RestS3Service.
+         (AWSCredentials. (context/aws-access-key-id)
+                          (context/aws-secret-access-key))))))

 (def #^{:private true} get-bucket
-     (memoize (fn [x]
-                (log/debug "Called get-bucket memoized fn on " (pr-str x))
-                (if (instance? S3Bucket x) x
-                    ;; .getBucket is not supported in jets3t 6.0, included in Hadoop
-                    (S3Bucket. x)))))
+     (memoize
+      (fn [x]
+        (log/debug "Called get-bucket memoized fn on " (pr-str x))
+        (if (instance? S3Bucket x) x
+            ;; .getBucket is not supported in jets3t 6.0, included in Hadoop
+            (S3Bucket. x)))))

 (defn- make-bucket-symbol [bucket]
   (with-meta (symbol (.getName bucket))


Increase the time to wait for instances to join the load balancer

--- backend/src/circle/backend/action/load_balancer.clj
+++ backend/src/circle/backend/action/load_balancer.clj
@@ -28,7 +28,7 @@
 (defn lb-healthy-retries
   "Number of times to retry when waiting for the LB to become healthy. Defn so it can be rebound w/ midje"
   []
-  12)
+  (* 3 12))

 (defaction wait-for-healthy []
   {:name "wait for nodes LB healthy"}


No longer need instr-type in Instr-gui namespace

--- src/overtime/instr_gui.clj
+++ src/overtime/instr_gui.clj
@@ -84,14 +84,14 @@
                    :items (concat listbox-rows slider-rows))))

 (defn show
-  [frame-key & {:keys [title listboxes sliders instr-type instr loc-x loc-y] :or {title "Instr GUI" listboxes [] sliders [] loc-x 0 loc-y 0}}]
+  [frame-key & {:keys [title listboxes sliders instr loc-x loc-y] :or {title "Instr GUI" listboxes [] sliders [] loc-x 0 loc-y 0}}]
   (let [f (ss/frame :title title :content "Placeholder...")
         p (make-panel frame-key listboxes sliders)]
-    (log/debug "Showing GUI for" frame-key ", list boxes:" listboxes ", sliders:" sliders ", instr:" instr-type "-" instr)
+    (log/debug "Showing GUI for" frame-key ", list boxes:" listboxes ", sliders:" sliders ", instr:" instr)
     (ss/config! f :content p)
     (-> f ss/pack! ss/show!)
     (doto f (.setLocation loc-x loc-y))
-    (swap! frames-data assoc frame-key {:frame f :sliders sliders :instr-type instr-type :instr instr})
+    (swap! frames-data assoc frame-key {:frame f :sliders sliders :instr instr})
     f))

 (defn- widget
@@ -120,9 +120,9 @@
     true))

 (defn set-instr
-  [frame-key instr-type instr]
-  (log/debug "Set instr for" frame-key "to" instr-type instr)
-  (swap! frames-data update frame-key assoc :instr-type instr-type :instr instr))
+  [frame-key instr]
+  (log/debug "Set instr for" frame-key "to" instr)
+  (swap! frames-data update frame-key assoc :instr instr))

 (comment
   (def listboxes {:grain-envs [:guass :expodec :sinc1 :sinc2 :sinc3 :sinc4 :sinc5 :sinc6 :sinc7 :sinc8 :sinc9 :sinc10]
@@ -135,5 +135,4 @@
             :sliders sliders
             :loc-x 2600
             :loc-y 200
-            :instr-type :instr
             :instr :foo))


turn version into a map

turn version into a map

--- src/overtone/sc/server.clj
+++ src/overtone/sc/server.clj
@@ -16,7 +16,10 @@
         [overtone.osc])
   (:require [overtone.util.log :as log]))

-(def OVERTONE-VERSION 0.3)
+(def OVERTONE-VERSION {:major 0
+                       :minor 4
+                       :patch 0
+                       :snapshot true})

 (defonce server*        (ref nil))
 (defonce server-thread* (ref nil))


Renamed function in the asset namespace where asset was part of the function name

--- src/retro_fever/asset.cljs
+++ src/retro_fever/asset.cljs
@@ -65,35 +65,35 @@
            :animation sprite/animation)
          options))

-(defn load-dependent-assets []
+(defn load-dependencies []
   "Runs through all assets with dependencies and adds them to the asset store"
   (doseq [{:keys [id dependency-id type options]} @dependent-assets]
     (let [image (get-in @asset-store dependency-id)]
       (swap! asset-store assoc-in id
              (assoc (create-by-type type (concat [image] options)) :loaded true)))))

-(defn- collapse-assets
+(defn- collapse
   "Helper function to check wheter all resources have been loaded"
   [data & [key sub-key]]
   (if (map? data)
     (keep (fn [[k v]]
-            (collapse-assets v k key)) data)
+            (collapse v k key)) data)
     (when (= key :loaded)
       (hash-map sub-key data))))

 (defn resources-loaded? []
   "Checks wheter all asynchronous loaded resources have completed"
-  (every? true? (vals (apply merge (flatten (collapse-assets @asset-store))))))
+  (every? true? (vals (apply merge (flatten (collapse @asset-store))))))

-(defn load-assets
+(defn load
   "Load assets based on a specification map"
-  [asset-spec]
+  [spec]
   (doseq [[k f] {:images load-image
                  :spritesheets load-spritesheet
                  :animations load-animation}]
-    (doall (map #(f %) (k asset-spec)))))
+    (doall (map #(f %) (k spec)))))

-(defn- get-asset
+(defn- get-from-store
   "Internal function to extrac assets from the asset store"
   [id]
   (get-in @asset-store id))
@@ -101,14 +101,14 @@
 (defn get-image
   "Extracts a given image from the asset store"
   [id]
-  (get-asset (add-id-prefix :images id)))
+  (get-from-store (add-id-prefix :images id)))

 (defn get-spritesheet
   "Extracts a given image from the asset store"
   [id]
-  (get-asset (add-id-prefix :spritesheets id)))
+  (get-from-store (add-id-prefix :spritesheets id)))

 (defn get-animation
   "Extracts a given animation from the asset store"
   [id]
-  (get-asset (add-id-prefix :animations id)))
+  (get-from-store (add-id-prefix :animations id)))


Update test_parser.clj

Update test_parser.clj

--- src/selmer/test_parser.clj
+++ src/selmer/test_parser.clj
@@ -2,9 +2,9 @@

 (declare parse expr-tag)

-(defn render [template params]
+(defn render [template args]
   (->> (for [element template]
-         (if (string? element) element (element params)))
+         (if (string? element) element (element args)))
        (apply str)))

 (defn read-char [rdr]
@@ -23,9 +23,10 @@

 (defn value-tag [{:keys [tag-value]}]
   (let [value (map keyword (.split tag-value "\\."))]
-    (fn [params] (get-in params value))))
+    (fn [args] (get-in args value))))

 #_((value-tag {:tag-value "foo.bar.baz"}) {:foo {:bar {:baz "ok"}}})
+;ok
 #_((value-tag {:tag-value "foo"}) {:foo "ok"})
 ;ok

@@ -42,10 +43,10 @@
              (if (= :value tag-type)
                {:tag-value (first content)}
                {:tag-name (first content)
-                :params (rest content)})))))
+                :args (rest content)})))))

 #_(read-tag-info (java.io.StringReader. "% for i in nums %}"))
-;{:params ("i" "in" "nums"), :tag-name "for", :tag-type :expr}
+;{:args ("i" "in" "nums"), :tag-name "for", :tag-type :expr}

 #_(read-tag-info (java.io.StringReader. "{ nums }}"))
 ;{:tag-value "nums", :tag-type :value}
@@ -56,8 +57,7 @@
     (loop [ch (read-char rdr)]
       (if (= \{ ch)
         (let [{:keys [tag-name tag-type] :as tag} (read-tag-info rdr)]
-          (when (not= close-tag tag-name)
-            (println tag)
+          (when (not= close-tag tag-name)
             (conj! content (.toString buf))
             (.setLength buf 0)
             (conj! content (if (= :value tag-type)
@@ -76,17 +76,24 @@
 ;"foo Bob bar "

 (def expr-tags
-  {:for {:content true
-         :close-tag "endfor"}})
+  {:for {:handler
+         (fn [args rdr]
+           (let [content (tag-content "endfor" rdr)]
+             (fn [args] (render content args))))}
+   :block {:handler
+           (fn [args rdr]
+             (let [content (tag-content "endblock" rdr)]
+               (fn [args] (render content args))))}})

-(defn expr-tag [{:keys [tag-name params]} rdr]
-  (let [{:keys [content close-tag]} (get expr-tags tag-name)]
-    (if content
-      (tag-content close-tag rdr))))
+(defn expr-tag [{:keys [tag-name args]} rdr]
+  (println tag-name args (get-in expr-tags [(keyword tag-name) :handler]))
+  ((get-in expr-tags [(keyword tag-name) :handler]) args rdr))

 (defn handle-tag [rdr]
-  (let [tag (read-tag-info rdr)]
-    ((if (:value tag) value-tag expr-tag) tag)))
+  (let [tag (read-tag-info rdr)]
+    (if (= :value (:tag-type tag))
+      (value-tag tag)
+      (expr-tag tag rdr))))

 (defn parse [file & state]
   (with-open [rdr (clojure.java.io/reader file)]
@@ -105,7 +112,7 @@
                 (do
                   (.append sb ch)
                   (recur state (.read rdr)))))))
+        (conj! template (.toString sb))
         (persistent! template))))

-
 #_(render (parse "home.html") {:name "Bob"})