give different name to tests jar artefact to avoid dependency issue with snapshots of the same named artefact but with different timestamp when uploaded to nexus in separate transactions (this is what boot's push does, even when provided a fileset with a set of jars).

--- ssclj/jar/build.boot
+++ ssclj/jar/build.boot
@@ -149,11 +149,16 @@
            (jar ;; :main 'com.sixsq.slipstream.ssclj.app.main
             )))

+(def tests-artef-name "SlipStreamCljResourcesTests-jar")
+(def tests-artef-pom-loc (str "com.sixsq.slipstream/" tests-artef-name))
+(def tests-artef-project-name (symbol tests-artef-pom-loc))
+(def tests-artef-jar-name (str tests-artef-name (get-env :version) "-tests.jar"))
+
 (deftask build-tests-jar
   "build jar with test runtime dependencies for connectors."
   []
   (comp
-    (pom :classifier "tests")
+    (pom :project tests-artef-project-name :classifier "tests")
     (sift
       :to-resource #{#"lifecycle_test_utils\.clj"
                      #"connector_test_utils\.clj"
@@ -163,13 +168,13 @@
                  #"pom.xml"
                  #"pom.properties"
                  })
-    (jar :file (str "SlipStreamCljResources-jar-" (get-env :version) "-tests.jar"))))
+    (jar :file tests-artef-jar-name)))

 (deftask mvn-build-tests-jar
   []
    (comp
      (build-tests-jar)
-     (install)
+     (install :pom tests-artef-pom-loc)
      (target)))

 (deftask mvn-test
@@ -197,5 +202,5 @@
          []
          (comp
            (mvn-build-tests-jar)
-           (push :repo "sixsq")))
-
+           (push :repo "sixsq" :pom tests-artef-pom-loc)))
+


Fixes to the ABACUS export file

Fixes to the ABACUS export file

- date format
- numbering of rows should start at 1
- windows line endings

--- src/mdr2/abacus.clj
+++ src/mdr2/abacus.clj
@@ -202,6 +202,8 @@
     (let [section (if (= k 4) "IBF" "ADO")]
       (list "D" section k (escape v)))))

+(def ^:private date-format "%1$td.%1$tm.%1$tY")
+
 (defn export
   "Export the state of a production as a csv-like structure, ready to
   be consumed by ABACUS"
@@ -209,27 +211,20 @@
            date id produced_date volumes] :as production}]
   (->> [(create-row 2 product_number)
         (create-row 233 total_time) ; in minutes
-        (create-row 106 state) ; Process Status Madras
-        (create-row 107 "") ; the Document Status Madras is no longer
-                            ; used but ABACUS still expects it. Just
-                            ; give it an empty string to chew on
+        (create-row 106 state)
         (create-row 276 audio_format)
         ;; FIXME: the number of CDs is only determined at the time of
         ;; archiving. Is this persisted in the db?
         (create-row 275 volumes) ; Number of CDs
         (create-row 277 multimedia_type)
-        ;; FIXME: again the date of the end of the production is only
-        ;; known once we start the archiving. Should this be persisted
-        ;; to the db?
-        (create-row 252 produced_date) ; Date of production end
-        (create-row 274 date) ; Date of production start
+        (create-row 252 (format date-format produced_date)) ; Date of production end
+        (create-row 274 (format date-format date)) ; Date of production start
         (create-row 4 (prod/dam-number production))] ; for legacy purposes
        (remove nil?) ; remove empty rows
        wrap-rows ; wrap the payload
-       (map-indexed #(conj %2 %1)) ; number each row
+       (map-indexed #(conj %2 (inc %1))) ; number each row starting at 1
        (map #(string/join "," %))
-       (map println-str)
-       (string/join)))
+       (string/join "\r\n"))) ; use cr/lf as this is consumed only on windows

 (defn export-file
   "Export the state of a production into a special file in


This needs to be a var to be visible in eval [IMMUTANT-575]

--- wildfly/src/immutant/wildfly.clj
+++ wildfly/src/immutant/wildfly.clj
@@ -45,38 +45,40 @@
     (URL. (str "file" (last match)))
     url))

-(let [^Class module-class-loader-class (memoize #(u/try-import 'org.jboss.modules.ModuleClassLoader))]
-  (defn- get-resource-loaders
-    [cl]
-    (when (module-class-loader-class)
-      (-> (doto (.getDeclaredMethod (module-class-loader-class) "getResourceLoaders"
-                  (make-array Class 0))
-            (.setAccessible true))
-        (.invoke cl (make-array Class 0)))))
+(def ^:no-doc ^Class module-class-loader-class
+  (memoize #(u/try-import 'org.jboss.modules.ModuleClassLoader)))

-  (defn ^:no-doc get-module-loader-urls [loader]
-    (->> loader
-      get-resource-loaders
-      (map (comp if-exists? vfs->file loader->url))
-      (keep identity)))
+(defn- get-resource-loaders
+  [cl]
+  (when (module-class-loader-class)
+    (-> (doto (.getDeclaredMethod (module-class-loader-class) "getResourceLoaders"
+                (make-array Class 0))
+          (.setAccessible true))
+      (.invoke cl (make-array Class 0)))))

-  (defn ^:no-doc extend-module-classloader-to-cjc []
-    (when (u/try-resolve 'clojure.java.classpath/URLClasspath)
-      (eval
-        `(extend-protocol clojure.java.classpath/URLClasspath
-           (module-class-loader-class)
-           (urls [cl#]
-             (get-module-loader-urls cl#))))))
+(defn ^:no-doc get-module-loader-urls [loader]
+  (->> loader
+    get-resource-loaders
+    (map (comp if-exists? vfs->file loader->url))
+    (keep identity)))

-  (defn ^:no-doc extend-module-classloader-to-dynapath []
-    (when (u/try-resolve 'dynapath.dynamic-classpath/DynamicClasspath)
-      (eval
-        `(extend-protocol dynapath.dynamic-classpath/DynamicClasspath
-           (module-class-loader-class)
-           (can-read? [cl#] true)
-           (can-add? [cl#] false)
-           (classpath-urls [cl#]
-             (get-module-loader-urls cl#)))))))
+(defn ^:no-doc extend-module-classloader-to-cjc []
+  (when (u/try-resolve 'clojure.java.classpath/URLClasspath)
+    (eval
+      `(extend-protocol clojure.java.classpath/URLClasspath
+         (module-class-loader-class)
+         (urls [cl#]
+           (get-module-loader-urls cl#))))))
+
+(defn ^:no-doc extend-module-classloader-to-dynapath []
+  (when (u/try-resolve 'dynapath.dynamic-classpath/DynamicClasspath)
+    (eval
+      `(extend-protocol dynapath.dynamic-classpath/DynamicClasspath
+         (module-class-loader-class)
+         (can-read? [cl#] true)
+         (can-add? [cl#] false)
+         (classpath-urls [cl#]
+           (get-module-loader-urls cl#))))))

 (defn ^:no-doc init-deployment
   "Initializes an in-container deployment. Should be used by the


added a `fact` doc-string

added a `fact` doc-string

--- src/midje/sweet.clj
+++ src/midje/sweet.clj
@@ -47,7 +47,23 @@
     `(do ~@foreground-forms)))

 (defmacro fact
-  ""
+  "A fact is a statement about code:
+
+  (fact \"one plus one is two\"
+    (+ 1 1) => 2)
+
+  You can make facts relative to other information:
+
+  (defn g [x] nil)
+  (defn f [x] (+ (g x) (g x)))
+
+  (fact \"f of some arg, named ..x.. calls g twice w/ the
+          same arg as was sent to f, and adds up the results\"
+    (f ..x..) => 12
+    (provided (g ..x..) => 6 :times 2))
+
+  For more info, see on the wiki:
+  metaconstants, checkers, arrows and specifying call counts"
   [& forms]
   (when (user-desires-checking?)
     (try


Add starting version of `midje-help`

Add starting version of `midje-help`

--- src/midje/sweet.clj
+++ src/midje/sweet.clj
@@ -27,6 +27,7 @@
             [midje.ideas.formulas :as formulas]
             [clojure.test :as ct]
             [midje.ideas.metadata :as metadata]
+            [midje.util.colorize :as color]
             midje.checkers))

 (immigrate 'midje.unprocessed)
@@ -163,3 +164,15 @@
   (let [[metadata body] (metadata/wrappable-metadata forms)]
     (metadata/with-wrapped-metadata metadata
       (midjcoexpand `(do ~@body)))))
+
+(try
+  (throw (Exception.))
+  (catch Exception e
+    (when-not (empty? (filter #(.contains % "clojure.main$repl$read_eval_print")
+                              (map str (.getStackTrace e))))
+      (println (color/note "For usage examples, see `(midje-help)`.")))))
+
+(defn midje-help
+  "Print useful information."
+  []
+  (println (color/fail "Not implemented yet.")))


Added profiling to import of data functions

--- src/kmg/datomic_helpers.clj
+++ src/kmg/datomic_helpers.clj
@@ -57,7 +57,7 @@
   "This function creates schema and imports knowledge base for IT data and users sample data"
   []
   (let [data-path (env :real-data-path)]
-    (import-knowledge-base-data data-path)
+    (time (import-knowledge-base-data data-path))
     (println "Knowledge base for IT imported. Press Ctrl+c to exit.")))
 ;;(delete-database)
 ;;(time (create-db-and-import-knowledge-base-4-it))
@@ -66,7 +66,7 @@
   "This function creates schema and imports knowledge base data and users sample data"
   []
   (let [data-path (env :sample-data-path)]
-    (import-knowledge-base-data data-path)
+    (time (import-knowledge-base-data data-path))
     (println "Sample data imported. Press Ctrl+c to exit.")))
 ;; (time (create-db-and-import-sample-data))


FlowAction schema enum was incorrectly defined

--- src/onyx/schema.clj
+++ src/onyx/schema.clj
@@ -186,7 +186,9 @@
    (s/optional-key :lifecycle/after-retry-segment) Function})

 (def FlowAction
-  (s/enum [:retry]))
+  (s/enum :retry))
+
+(def UnsupportedFlowKey
   (s/pred (fn [k]
             (or (not (keyword? k))
                 (not (= "flow" (namespace k)))))


--- src/clj/forma/hadoop/jobs/preprocess.clj
+++ src/clj/forma/hadoop/jobs/preprocess.clj
@@ -74,8 +74,8 @@
           src (s/sample-modis m-res dataset pix-tap line-tap agg)]
       (?- (chunk-tap output-path)
           (sparse-windower src
-                           ["?sample" "?line"] "?val"
-                           width height -9999)))))
+                           ["?sample" "?line"] "?val" width height
+                           -9999)))))
 (defn modis-main
   "Example usage:

@@ -92,6 +92,10 @@
   "TODO: Example usage."
   [path output-path & tiles]
   (rain-chunker "1000"
+<<<<<<< HEAD
+=======
+                0.5
+>>>>>>> Moved lots of stuff from static to preprocess.
                 static/chunk-size
                 (map read-string tiles)
                 (s3-path path)


Added preconditions for spatial res as string

--- src/clj/forma/hadoop/jobs/preprocess.clj
+++ src/clj/forma/hadoop/jobs/preprocess.clj
@@ -24,6 +24,7 @@
 (defmain PreprocessRain
   "See project wiki for example usage."
   [path pail-path s-res & countries]
+  {:pre [(string? s-res)]}
   (let [countries (map read-string countries)]
     (rain-chunker s-res
                   static/chunk-size
@@ -42,6 +43,7 @@
 (defmain PreprocessStatic
   "See project wiki for example usage."
   [dataset ascii-path output-path s-res & countries]
+  {:pre [(string? s-res)]}
   (static-chunker s-res
                   static/chunk-size
                   (->> countries
@@ -56,7 +58,8 @@
   "TODO: This is only good for hansen datasets looking to be combined
   Tidy up. This needs to be combined with PreprocessStatic."
   [dataset ascii-path pail-path s-res & countries]
-  {:pre [(#{"hansen" "vcf"} dataset)]}
+  {:pre [(#{"hansen" "vcf"} dataset)
+         (string? s-res)]}
   (with-fs-tmp [_ tmp-dir]
     (let [line-tap (hfs-textline ascii-path)
           pix-tap  (->> countries


formatting

formatting

--- src/clj/storm/starter/clj/word_count.clj
+++ src/clj/storm/starter/clj/word_count.clj
@@ -1,6 +1,7 @@
 (ns storm.starter.clj.word-count
-  (:import backtype.storm.LocalCluster)
-  (:use [backtype.storm clojure config]))
+  (:import [backtype.storm StormSubmitter LocalCluster])
+  (:use [backtype.storm clojure config])
+  (:gen-class))

 (defspout sentence-spout ["sentence"]
   [conf context collector]
@@ -43,14 +44,19 @@
          )))))

 (defn mk-topology []
+
   (topology
    {1 (spout-spec sentence-spout)
     2 (spout-spec (sentence-spout-parameterized
                    ["the cat jumped over the door"
                     "greetings from a faraway land"])
                   :p 2)}
-   {3 (bolt-spec {1 :shuffle 2 :shuffle} split-sentence :p 5)
-    4 (bolt-spec {3 ["word"]} word-count :p 6)}))
+   {3 (bolt-spec {1 :shuffle 2 :shuffle}
+                 split-sentence
+                 :p 5)
+    4 (bolt-spec {3 ["word"]}
+                 word-count
+                 :p 6)}))

 (defn run-local! []
   (let [cluster (LocalCluster.)]
@@ -58,3 +64,11 @@
     (Thread/sleep 10000)
     (.shutdown cluster)
     ))
+
+(defn -main [name]
+  (StormSubmitter/submitTopology
+   name
+   {TOPOLOGY-DEBUG true
+    TOPOLOGY-WORKERS 3}
+   (mk-topology)))
+


more work on overlay

more work on overlay

--- src/cljs/defender_cljs/overlay/core.cljs
+++ src/cljs/defender_cljs/overlay/core.cljs
@@ -8,11 +8,20 @@
 (def hud-line-width 5)
 (def hud-text-size 20)

+;;top of the screen overlay. bounds for the map space
+(def left-bound (/ c/hud-width 3))
+(def right-bound (* left-bound 2))
+(def top-bound c/hud-height)
+(def bottom-bound (- c/hud-height c/top-overlay-height))
+
+(def width-segments (/ (- right-bound left-bound)) 7)
+(def inner-left-bound (* 3 width-segments))
+(def inner-right-bound (* 4 width-segments))
+
+
+
 (defn init-hud-outline [scene]
-  (let [left-bound (/ c/hud-width 3)
-        right-bound (* left-bound 2)
-        top-bound c/hud-height
-        bottom-bound (- c/hud-height c/top-overlay-height)
+  (let [

         ;;line properties
         line-color (c/colors :blue)
@@ -48,7 +57,11 @@
          [[left-bound (- top-bound (/ line-width 2))]
           [right-bound (- top-bound (/ line-width 2))]]
          :color line-color
-         :line-width line-width)]
+         :line-width line-width)
+
+        white-left-bound nil
+
+        ]

     (.add scene straight-line)
     (.add scene left-line)


Update step methods to take state value rather than change app-state atom

--- src/cljs/pushpopchestnutreless/core.cljs
+++ src/cljs/pushpopchestnutreless/core.cljs
@@ -1,47 +1,48 @@
 (ns pushpopchestnutreless.core
-  (:require [reagent.core :as reagent :refer [atom]]))
+  (:require [reagent.core :as reagent :refer [atom]]
+            [cljs.pprint :as pp]))

 (enable-console-print!)

 (defonce app-state (atom {:text "Hello Chestnut!" :count 0}))

 (defmulti step
-  (fn [{:keys [id]}]
+  (fn [_ {:keys [id]}]
    id))

+;; UPDATE
+(defmethod step :change-text [state m]
+  (assoc state :text (:text m)))

-;; UPDATE
-(defmethod step :change-text [m]
-  (swap! app-state assoc :text (:text m)))
+(defmethod step :inc [state m]
+  (update state :count inc))

-(defmethod step :inc [m]
-  (swap! app-state update :count inc))
+(defmethod step :dec [state m]
+  (update state :count dec))

-(defmethod step :dec [m]
-  (swap! app-state update :count dec))
+(defmethod step :inc2 [state m]
+  (update state :count2 inc))

-(defmethod step :inc2 [m]
-  (swap! app-state update :count2 inc))
-
-(defmethod step :dec2 [m]
-  (swap! app-state update :count2 dec))
-
+(defmethod step :dec2 [state m]
+  (update state :count2 dec))

 ; VIEW HELPERS

+(defn do-step [msg]
+  (swap! app-state step msg))
+
 (defn on-change [msg-id]
-  #(step {:id msg-id
-          :text (-> % .-target .-value)}))
+  #(do-step {:id msg-id
+             :text (-> % .-target .-value)}))

 (defn on-click [msg-id]
-  #(step {:id msg-id}))
+  #(do-step {:id msg-id}))

 ;: VIEW

 (defn counter [count inc-msg dec-msg]
-  (.log js/console (str "render counter " inc-msg))
   [:div
    [:h2 (str "count " count)]
    [:button
@@ -52,7 +53,6 @@
     "-"]])

 (defn greeting [state]
-  (.log js/console "render greeting")
   [:div
    [:h1 (:text state)]
    [:input


Removed test leftover from fixing drag and drop.

--- src/clojure/staircase/views/projects.clj
+++ src/clojure/staircase/views/projects.clj
@@ -142,7 +142,6 @@
   [:tr ;; The branch nodes, ie. the sub-projects
    {:ng-repeat "project in appView.currentProject.child_nodes | orderBy:appView.tableSort"
     :im-dropzone "project"
-    ; :onDrop "alert('test')"}
     :im-drop-action "appView.dropped(dragged, project)"}

    ;; Editable and clickable folder title


fix duplicating docs

fix duplicating docs

--- src/pc/http/doc.clj
+++ src/pc/http/doc.clj
@@ -21,7 +21,7 @@
   (let [doc (doc-model/create-public-doc! (merge {:document/name (str "Copy of " document-name)
                                                   :document/chat-bot (rand-nth chat-bot-model/chat-bots)}
                                                  (when (:cust/uuid cust) {:document/creator (:cust/uuid cust)})))]
-    (if-let [layers (get docs document-name)]
+    (if-let [layers (get (docs) document-name)]
       @(d/transact (pcd/conn) (conj (map #(assoc %
                                             :db/id (d/tempid :db.part/user)
                                             :document/id (:db/id doc))


Test the whole index

Test the whole index

--- src/com/wsscode/pathom/connect/test.cljc
+++ src/com/wsscode/pathom/connect/test.cljc
@@ -171,22 +171,32 @@
                             (remove (get-in db [::call-history sym] {}))
                             (first))]
          (test-resolver env resolver input')
-         (do
-           (log! env resolver {:in in-data :out ::end-of-input})
-           env)))))
+         (log! env resolver {:in in-data :out ::end-of-input})))))

   ([{::keys [data-bank] :as env}
     {::p.connect/keys [sym] :as resolver}
     input]
    (let [f (resolve sym)]
-     (let [out (some-> (f env input)
-                       (dissoc ::p.connect/env))]
+     (let [out (try
+                 (some-> (f env input)
+                         (dissoc ::p.connect/env))
+                 (catch Throwable e
+                   e))]
        (swap! data-bank update-in [::call-history sym] assoc input out)
        (log! env resolver {:in input :out out})
-       (if (not= ::resolver-error out)
+       (if (map? out)
          (swap! data-bank bank-add out)))
      env)))

 (defn test-index
-  [env]
-  )
+  [{::keys           [data-bank]
+    ::p.connect/keys [indexes] :as env}]
+  (let [resolvers (-> indexes ::p.connect/index-resolvers)
+        res-keys  (set (keys resolvers))]
+    (loop [missing res-keys]
+      (if (seq missing)
+        (let [sym (first missing)]
+          (if-not (test-resolver env (p.connect/resolver-data env sym))
+            (swap! data-bank update-in [::call-history sym] assoc ::error ::none))
+          (recur (set/difference res-keys (->> (get @data-bank ::call-history) (keys) (set)))))
+        env))))


Add check-box? function

Add check-box? function

--- src/play_clj/ui.clj
+++ src/play_clj/ui.clj
@@ -187,6 +187,11 @@
   [entity k & options]
   `(u/call! ^Checkbox (u/get-obj ~entity :object) ~k ~@options))

+(defn check-box?
+  "Returns true if `entity` is a `check-box`."
+  [entity]
+  (isa? (type (u/get-obj entity :object)) Checkbox))
+
 ; container

 (defn container*


Improve partition-approx logic.

Improve partition-approx logic.

--- src/merkle_db/partition.clj
+++ src/merkle_db/partition.clj
@@ -34,18 +34,21 @@
 ;; ## Utilities

 (defn- partition-approx
-  "Returns a lazy sequence of lists containing the elements of `coll` in order,
-  where the average of the list sizes is approximately `target`."
-  [target coll]
-  ; FIXME: still not as balanced as it could be
+  "Returns a lazy sequence of `n` lists containing the elements of `coll` in
+  order, where each list is approximately the same size."
+  [n coll]
   (->>
-    [nil 0.0 coll]
+    [nil
+     (->> (range (inc n))
+          (map #(int (* (/ % n) (count coll))))
+          (partition 2 1))
+     coll]
     (iterate
-      (fn [[_ frac more]]
-        (let [length (cond-> (int target) (<= 1.0 frac) inc)]
-          [(seq (take length more))
-           (- (+ frac target) length)
-           (drop length more)])))
+      (fn [[_ [[start end :as split] & splits] xs]]
+        (when-let [length (and split (- end start))]
+          [(seq (take length xs))
+           splits
+           (drop length xs)])))
     (drop 1)
     (take-while first)
     (map first)))
@@ -305,9 +308,7 @@
   (let [records (sort-by first key/compare records)
         limit (or (::limit parameters) 100000)
         families (or (::data/families parameters) {})
-        target-count (/ (count records)
-                        (inc (int (/ (count records)
-                                     limit))))]
+        part-count (inc (int (/ (count records) limit)))]
     (map
       (fn make-partition
         [partition-records]
@@ -324,7 +325,7 @@
                      (map (juxt key #(tablet/from-records f (val %))))
                      (map (partial apply store-tablet! store))
                      (into {}))})
-      (partition-approx target-count records))))
+      (partition-approx part-count records))))


Reduce depth

Reduce depth

--- src/obb_rules/ai/alamo.cljc
+++ src/obb_rules/ai/alamo.cljc
@@ -11,7 +11,7 @@
             [obb-rules.result :as result]
             [obb-rules.board :as board]))

-(def element-depth 10)
+(def element-depth 5)

 (defmulti actions
   "Returns a list of actions to apply to the current game"


Schema check task maps

Schema check task maps

--- src/onyx/plugin/datomic.clj
+++ src/onyx/plugin/datomic.clj
@@ -7,7 +7,60 @@
             [onyx.static.default-vals :refer [defaults]]
             [onyx.static.uuid :refer [random-uuid]]
             [onyx.extensions :as extensions]
+            [schema.core :as s]
+            [onyx.schema :as os]
             [taoensso.timbre :refer [info debug fatal]]))
+
+;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;
+;; task schemas
+
+(def UserTaskMapKey
+  (os/build-allowed-key-ns :datomic))
+
+(def DatomicReadLogTaskMap
+  (s/->Both [os/TaskMap
+             {:datomic/uri s/Str
+              (s/optional-key :datomic/log-start-tx) s/Int
+              (s/optional-key :datomic/log-end-tx) s/Int
+              :checkpoint/force-reset? s/Bool
+              (s/optional-key :onyx/max-peers) (s/enum 1)
+              (s/optional-key :onyx/n-peers) (s/enum 1)
+              UserTaskMapKey s/Any}]))
+
+(def DatomicReadDatomsTaskMap
+  (s/->Both [os/TaskMap
+             {:datomic/uri s/Str
+              :datomic/t s/Int
+              :datomic/datoms-index s/Keyword
+              :datomic/datoms-components [s/Any]
+              :datomic/datoms-per-segment s/Int
+              (s/optional-key :onyx/max-peers) (s/enum 1)
+              (s/optional-key :onyx/n-peers) (s/enum 1)
+              UserTaskMapKey s/Any}]))
+
+
+(def DatomicReadIndexRangeTaskMap
+  (s/->Both [os/TaskMap
+             {:datomic/uri s/Str
+              :datomic/t s/Int
+              :datomic/index-attribute s/Any
+              :datomic/index-range-start s/Any
+              :datomic/index-range-end s/Any
+              :datomic/datoms-per-segment s/Int
+              (s/optional-key :onyx/max-peers) (s/enum 1)
+              (s/optional-key :onyx/n-peers) (s/enum 1)
+              UserTaskMapKey s/Any}]))
+
+(def DatomicWriteDatomsTaskMap
+  (s/->Both [os/TaskMap
+             {:datomic/uri db-uri
+              (s/optional-key :datomic/partition) (s/either s/Int s/Keyword)
+              (s/optional-key :onyx/max-peers) (s/enum 1)
+              (s/optional-key :onyx/n-peers) (s/enum 1)
+              UserTaskMapKey s/Any}]))
+
+;;; Helpers

 (defn safe-connect [task-map]
   (if-let [uri (:datomic/uri task-map)]
@@ -45,11 +98,13 @@
 (defn datoms-sequence [db task-map]
   (case (:onyx/plugin task-map)
     ::read-datoms
-    (let [datoms-components (or (:datomic/datoms-components task-map) [])
+    (let [_ (s/validate DatomicReadDatomsTaskMap task-map)
+          datoms-components (or (:datomic/datoms-components task-map) [])
           datoms-index (:datomic/datoms-index task-map)]
       (apply d/datoms db datoms-index datoms-components))
     ::read-index-range
-    (let [attribute (:datomic/index-attribute task-map)
+    (let [_ (s/validate DatomicReadIndexRangeTaskMap task-map)
+          attribute (:datomic/index-attribute task-map)
           range-start (:datomic/index-range-start task-map)
           range-end (:datomic/index-range-end task-map)]
       (d/index-range db attribute range-start range-end))))
@@ -66,6 +121,7 @@
   (when-not (or (= 1 (:onyx/max-peers task-map))
                 (= 1 (:onyx/n-peers task-map)))
     (throw (ex-info "Read datoms tasks must set :onyx/max-peers 1" task-map)))
+
   (let [_ (extensions/write-chunk log :chunk {:chunk-index -1 :status :incomplete} task-id)
         content (extensions/read-chunk log :chunk task-id)]
     (if (= :complete (:status content))
@@ -258,6 +314,8 @@
   (when-not (or (= 1 (:onyx/max-peers task-map))
                 (= 1 (:onyx/n-peers task-map)))
     (throw (ex-info "Read log tasks must set :onyx/max-peers 1" task-map)))
+  (s/validate DatomicReadLogTaskMap task-map)
+
   (let [start-tx (:datomic/log-start-tx task-map)
         max-tx (:datomic/log-end-tx task-map)
         {:keys [read-ch shutdown-ch commit-ch]} pipeline
@@ -411,7 +469,7 @@
 ;; output plugins

 (defn inject-write-tx-resources
-  [{:keys [onyx.core/pipeline]} lifecycle]
+  [{:keys [onyx.core/pipeline onyx.core/task-map]} lifecycle]
   {:datomic/conn (:conn pipeline)})

 (defn inject-write-bulk-tx-resources
@@ -440,6 +498,7 @@

 (defn write-datoms [pipeline-data]
   (let [task-map (:onyx.core/task-map pipeline-data)
+        _ (s/validate DatomicWriteDatomsTaskMap task-map)
         conn (safe-connect task-map)
         partition (:datomic/partition task-map)]
     (->DatomicWriteDatoms conn partition)))
@@ -464,6 +523,7 @@

 (defn write-bulk-datoms [pipeline-data]
   (let [task-map (:onyx.core/task-map pipeline-data)
+        _ (s/validate DatomicWriteDatoms task-map)
         conn (safe-connect task-map)]
     (->DatomicWriteBulkDatoms conn)))


Fix error message

Fix error message

--- src/onyx/plugin/datomic.clj
+++ src/onyx/plugin/datomic.clj
@@ -255,7 +255,7 @@
                        :datomic/log-end-tx end-tx
                        :checkpointed-tx checkpoint-tx})))
     (when (and end-tx (>= checkpoint-tx end-tx))
-      (throw (ex-info "Checkpointed transaction is greater than :datomic/log-start-tx"
+      (throw (ex-info "Checkpointed transaction is greater than :datomic/log-end-tx"
                       {:datomic/log-start-tx start-tx
                        :datomic/log-end-tx end-tx
                        :checkpointed-tx checkpoint-tx})))))


/home is more common than /landing

/home is more common than /landing

--- frontend/routes.cljs
+++ frontend/routes.cljs
@@ -166,7 +166,7 @@
       (open-to-inner! nav-ch :dashboard params)
       (open-to-outer! nav-ch :landing params)))

-  (defroute v1-root (FragmentRoute. "/landing") {:as params}
+  (defroute v1-root (FragmentRoute. "/home") {:as params}
     (open-to-outer! nav-ch :landing params)))

 (defn define-spec-routes! [nav-ch]


extract out worker core fns

extract out worker core fns

--- src/overtone/libs/event.clj
+++ src/overtone/libs/event.clj
@@ -21,6 +21,26 @@
   (future (apply log/debug msg args)))

 (defrecord LossyWorker [queue worker current-val])
+
+(defn- worker-core
+  [update-fn current-val* last-val*]
+  (let [current @current-val*
+        last @last-val*]
+    (when (not= current last)
+      (update-fn current)
+      (reset! last-val* current)) ))
+
+(defn- worker
+  [queue update-fn current-val* last-val*]
+  (while (not= (.take queue) :die)
+    (worker-core update-fn current-val* last-val*))
+
+  (log-event "Killing Lossy worker"))
+
+(defn- mk-worker
+  [queue update-fn current-val* last-val*]
+  (fn []
+    (worker queue update-fn current-val* last-val*)))

 (defn- lossy-worker
   "Create a lossy worker which will call update-fn on a separate thread
@@ -40,15 +60,7 @@
   (let [current-val* (atom nil)
         last-val*    (atom (gensym))
         queue        (LinkedBlockingQueue.)
-        work         (fn []
-                       (while (not= (.take queue) :die)
-                         (let [current @current-val*
-                               last @last-val*]
-                           (when (not= current last)
-                             (update-fn current)
-                             (reset! last-val* current))))
-                       (log-event "Killing Lossy worker"))
-        worker       (Thread. work)]
+        worker       (Thread. (mk-worker queue update-fn current-val* last-val*))]
     (.start worker)
     (LossyWorker. queue worker current-val*)))


simplify redundant boolean expression

simplify redundant boolean expression

--- src/parinfer/formatter.cljs
+++ src/parinfer/formatter.cljs
@@ -287,9 +287,8 @@
   (let [closing-delim? (isa? char-hierarchy ch :close)
         insert-at-char? (and (not= "" ch)
                              (not (whitespace? ch))
-                             (or (and (= line-no cursor-line)
-                                      closing-delim?)
-                                 (not closing-delim?))
+                             (or (not closing-delim?)
+                                 (= line-no cursor-line))
                              (in-code? stack))

         ;; Add potential insert point for closing delimiters if required.


removed 'create database' step from init

--- src/pe_fp_app/lifecycle.clj
+++ src/pe_fp_app/lifecycle.clj
@@ -64,8 +64,7 @@
 (defn init-database
   []
   ;; Database setup
-  (log/info "Proceeding to create database")
-  (jcore/create-database config/db-spec-without-db config/fp-db-name)
+  (log/info "Proceeding to setup database")

   ;; Create schema version table
   (j/db-do-commands config/db-spec true uddl/schema-version-ddl)


Add toString implementation to TextNode

Add toString implementation to TextNode

For ease of debugging, REPL interaction etc, add toString
implementation for TextNode which simply returns the node text.

--- src/selmer/node.clj
+++ src/selmer/node.clj
@@ -23,4 +23,6 @@
 (deftype TextNode [text]
   INode
   (render-node [this context-map]
+    text)
+  (toString [_]
     text))


lower cache threshold

lower cache threshold

--- src/shorty/core.clj
+++ src/shorty/core.clj
@@ -18,7 +18,7 @@
 (log/start! log)
 (log/set-debug!)

-(def lru-threshold (or (:cache env) 10000))
+(def lru-threshold (or (:cache env) 500))
 (def decode* (memo/lru decode :lru/threshold lru-threshold))
 (def find-url* (memo/lru find-url :lru/threshold lru-threshold))
 (def decode+find-url (comp find-url* decode*))


Revert change to the add-timer! function

--- src/play_clj/core_utils.clj
+++ src/play_clj/core_utils.clj
@@ -111,7 +111,7 @@
     new-timer))

 (defn add-timer!
-  "Creates a [Timer](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Timer.html)
+  "Returns a [Timer](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Timer.html)
 which will fire the :on-timer function one or more times (depending on the given
 arguments). In the :on-timer function, the id will be passed in the screen map.
 If a timer with that id already exists in the screen, it will be stopped and
@@ -124,14 +124,14 @@
     ; wait 2 seconds, run once, and then run 3 more times at 10 second intervals
     (add-timer! screen :spawn-enemy 2 10 3)"
   ([screen id delay]
-    (-> (create-and-add-timer! screen id)
-        (.scheduleTask (task* screen id) delay)))
+    (doto (create-and-add-timer! screen id)
+      (.scheduleTask (task* screen id) delay)))
   ([screen id delay interval]
-    (-> (create-and-add-timer! screen id)
-        (.scheduleTask (task* screen id) delay interval)))
+    (doto (create-and-add-timer! screen id)
+      (.scheduleTask (task* screen id) delay interval)))
   ([screen id delay interval repeat]
-    (-> (create-and-add-timer! screen id)
-        (.scheduleTask (task* screen id) delay interval repeat))))
+    (doto (create-and-add-timer! screen id)
+      (.scheduleTask (task* screen id) delay interval repeat))))

 (defn remove-timer!
   "Stops and removes the timer associated with `id`, returning it or nil if not


Fix NPE in locality calculation with CDH4 API

--- src/main/hbase_region_inspector/core.clj
+++ src/main/hbase_region_inspector/core.clj
@@ -291,7 +291,8 @@
         (for [[table props] grouped]
           [table
            (let [with-locality
-                 (let [{loc :local-size-mb tot :store-file-size-mb} props]
+                 (let [{loc :local-size-mb tot :store-file-size-mb
+                        :or {loc 0 tot 0}} props]
                    (if (pos? tot)
                      (assoc props :locality (* 100 (/ loc tot)))
                      props))]


Fix for notifications fix

Fix for notifications fix

--- src/pomo/notifications.cljs
+++ src/pomo/notifications.cljs
@@ -6,7 +6,7 @@
   "denied")

 (defonce notifications
-  (atom (= "granted" (get-permission)))
+  (atom (= "granted" (get-permission))))

 (when (= "default" (get-permission))
   "default" (.requestPermission js/Notification #(reset! notifications (= % "granted"))))


Fix logic that checks watch key validity

--- boot/worker/src/boot/watcher.clj
+++ boot/worker/src/boot/watcher.clj
@@ -82,15 +82,18 @@
         doreg   #(register-recursive %1 %2 [:create :modify :delete])]
     (doseq [path paths] (doreg service (io/file path)))
     (-> #(let [watch-key (take-watch-key service)]
-           (doseq [event (and watch-key (.isValid watch-key) (.pollEvents watch-key))]
-             (let [dir     (.toFile (.watchable watch-key))
-                   changed (io/file dir (str (.context event)))
-                   etype   (enum->kw service (.kind event))
-                   dir?    (.isDirectory changed)]
-               (cond
-                 (and dir? (= :create etype)) (doreg service changed)
-                 (not dir?) (.offer queue (.getPath changed)))))
-           (and watch-key (.reset watch-key) (recur)))
+           (when watch-key
+             (if-not (.isValid watch-key)
+               (println "watch service: invalid watch key")
+               (do (doseq [event (.pollEvents watch-key)]
+                     (let [dir     (.toFile (.watchable watch-key))
+                           changed (io/file dir (str (.context event)))
+                           etype   (enum->kw service (.kind event))
+                           dir?    (.isDirectory changed)]
+                       (cond
+                         (and dir? (= :create etype)) (doreg service changed)
+                         (not dir?) (.offer queue (.getPath changed)))))
+                   (and watch-key (.reset watch-key) (recur))))))
       Thread. .start)
     service))


Fix spelling mistake in immutant.caching.cache docs

Should be `:optimistic`, not `:optimisitic`

--- caching/src/immutant/caching.clj
+++ caching/src/immutant/caching.clj
@@ -77,7 +77,7 @@

    Transactions: caches can participate in transactions when a
    TransactionManager is available. The locking scheme may be either
-   :optimisitic or :pessimistic
+   :optimistic or :pessimistic

    * :transactional? - whether the cache is transactional [false]
    * :locking - transactional locking scheme [:optimistic]


Sort rollups before forced flushing.

Sort rollups before forced flushing.

--- src/org/spootnik/cyanite/store_cache.clj
+++ src/org/spootnik/cyanite/store_cache.clj
@@ -45,7 +45,7 @@
                              @pkeys)) ttl)))
       (swap! mkeys #(dissoc % mkey))
       (catch Exception e
-        (info e "Cache flushing exception")))))
+        (error e "Cache flushing exception")))))

 (defn- run-delayer!
   [rollup fn-flusher]
@@ -75,7 +75,8 @@
                          (with-meta pkeys {:fn-flusher fn-flusher
                                            :delayer delayer
                                            :flusher flusher
-                                           :data (atom {})})))
+                                           :data (atom {})
+                                           :rollup rollup})))
                 (assoc % mkey pkeys))))
     (get @mkeys mkey)))

@@ -89,15 +90,19 @@
 (defn- run-flusher!
   [mkeys]
   (info "Flushing the store cache...")
-  (doseq [[mkey pkeys] @mkeys]
-    (let [m (meta @pkeys)
-          delayer (get m :delayer nil)
-          flusher (get m :flusher nil)]
-      (when delayer
-        (future-cancel delayer)
-        (when flusher
-          (deref flusher)))))
-  (info "The store cache has been flushed"))
+  (try
+    (let [sorted-mkeys (sort-by #(:rollup (meta (get mkeys (first %)))) @mkeys)]
+      (doseq [[mkey pkeys] sorted-mkeys]
+        (let [m (meta @pkeys)
+              delayer (get m :delayer nil)
+              flusher (get m :flusher nil)]
+          (when delayer
+            (future-cancel delayer)
+            (when flusher
+              (deref flusher))))))
+    (info "The store cache has been flushed")
+    (catch Exception e
+      (error e "Cache flushing exception"))))

 (defn in-memory-cache
   [config]


update when video id changes

update when video id changes

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -171,7 +171,8 @@
         (let [remaining-entries (entry-res/list-all-entries-by-board conn (:uuid old-board))]
           (board-res/maybe-delete-draft-board conn org old-board remaining-entries user)))
       (timbre/info "Updated entry for:" entry-for)
-      (handle-video-data conn updated-result)
+      (when (not= (:video-id updated-entry) (:video-id entry))
+        (handle-video-data conn updated-result))
       (notification/send-trigger! (notification/->trigger :update org board {:old entry :new updated-result} user nil))
       {:updated-entry (assoc updated-result :board-name (:name board))})


Fix typo in fn name.

Fix typo in fn name.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -612,7 +612,7 @@
             board (:existing-board ctx)
             entry (:existing-entry ctx)
             user (:user ctx)]
-    (if-let [updated-entry (entry-res/add-labels! conn (:uuid entry) label-uuids user)]
+    (if-let [updated-entry (entry-res/remove-labels! conn (:uuid entry) label-uuids user)]
       (do
         (timbre/debugf "Labels %s removed by user %s on entry %s" label-uuids (-> ctx :user :user-id) (:uuid entry))
         {:updated-entry (api-common/rep updated-entry)})


Return measurement from `rand-shmin`

Return measurement from `rand-shmin`

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -261,9 +261,12 @@
   (make-measurement (Math/abs (tuc/draw-normal 5061 121))
                     :psi))

-(defn rand-shmin []
-  (make-measurement (Math/abs (tuc/draw-normal 2.29 0.05))
-                    :psi))
+(defn rand-shmin
+  ([]
+   (let [pressure-unit (rand-pressure-unit)]
+     (rand-shmin pressure-unit)))
+  ([pressure-unit]
+   (pressure-as (make-measurement (Math/abs (tuc/draw-normal 2.29 0.05)) :psi) pressure-unit)))

 (defn rand-cluster-count []
   (inc (rand-nth (range 2 7))))


frame tests work

frame tests work

--- clojure_dmap/utilities/frame.clj
+++ clojure_dmap/utilities/frame.clj
@@ -157,11 +157,8 @@
 	 (do
 		(println "print-frame frame name:" frame-name " contents:" (frame-name frame-of))
 		(doseq [s (get-specializations frame-name)] (print-frame s))
-		(doseq [a (get-abstractions frame-name)] (print-frame a)) )) )
-
-		;;(assert (= (find-ancestors :abs-frame-2), (list ))
-		;;(assert (= (find-ancestors :test-frame-4), (list :abs-frame-2 ))
-		;;(assert (= (find-ancestors :sec-frame-2), (list :test-frame-4 :abs-frame-2 ))
+		(doseq [a (get-abstractions frame-name)] (print-frame a)) )) )
+
 (defn find-ancestors
 	"Go up the abstraction hierarchy and collect specializaionts/abstractions"
 	{:test #(do
@@ -169,11 +166,11 @@
 		(create-frame :test-frame-4 (list :test-slot-1 :test-slot-2) (list "a" "b") (list :spec-frame-2) (list :abs-frame-2) )
 		(create-frame :spec-frame-2 (list :spec-slot-1 :spec-slot-2) (list "x" "z") (list)               (list :test-frame-4) )
 		(println "ANCESTORS abs " (find-ancestors :abs-frame-2))
-		(println "")
 		(println "ANCESTORS test" (find-ancestors :test-frame-4))
-		(println "")
 		(println "ANCESTORS spec" (find-ancestors :spec-frame-2))
-		(println "")
+		(assert (= (find-ancestors :abs-frame-2), #{:abs-frame-2}))
+		(assert (= (find-ancestors :test-frame-4), #{ :abs-frame-2 :test-frame-4}))
+		(assert (= (find-ancestors :spec-frame-2), #{ :spec-frame-2 :abs-frame-2 :test-frame-4 }))
 	)}
 	[frame-name ]
 		(loop [	loop-frame frame-name
@@ -187,17 +184,16 @@
 							nil)]
 					(cond
 						(<= (count (difference  new-ancestor-set visited-set)) 0)
-						ancestor-set
+						new-ancestor-set
 						:t
 						(recur
-							(first (difference ancestor-set visited-set) )
+							(first (difference new-ancestor-set visited-set) )
 							new-ancestor-set
 							(conj visited-set loop-frame) )))))

 (defn get-feature
-	"looks first in the native frame, then abstractions, then specializations, returning the first found
-	this is disgusting. It climbs the hierarchy and recurses down making an infinite loop: FIXME TODO"
+	"looks first in the native frame, then abstractions, then specializations, returning the first found this is disgusting. It climbs the hierarchy and recurses down making an infinite lewp FIXME TODO"
 	{:test #(do
 		(create-frame :test-frame-4 (list :test-slot-1 :test-slot-2) (list "a" "b") (list) (list))
 		(create-frame :spec-frame-2 (list :spec-slot-1 :spec-slot-2) (list "x" "z") (list) (list))
@@ -205,9 +201,9 @@
 		(add-specialization :test-frame-4 :spec-frame-2)
 		(add-abstraction :test-frame-4 :abs-frame-2)

-		(println "testing get-feature with this frame:" )
+		(println "testing get-feature with this frame")
 		(print-frame :test-frame-4)
-		;(println "test get-feature:"  (get-feature :test-frame-4 :test-slot-1))
+		;(println "test get-feature"  (get-feature :test-frame-4 :test-slot-1))
 		;(assert (=  (get-feature :test-frame-4 :test-slot-1) "a"))
 		;(assert (=  (get-feature :test-frame-4 :test-slot-2) "b"))


Remove unused alias to uuid generation.

Remove unused alias to uuid generation.

--- frontend/src/uxbox/util/uuid.cljs
+++ frontend/src/uxbox/util/uuid.cljs
@@ -22,11 +22,7 @@
   [v]
   (= zero v))

-(defn v4
+(defn random
   "Generate a v4 (random) UUID."
   []
   (uuid (impl/v4)))
-
-(def random
-  "Alias for `uxbox.util.uuid/v4`."
-  v4)


Change URL to API

Change URL to API

--- frontend/src/cruncher/config.cljs
+++ frontend/src/cruncher/config.cljs
@@ -1,6 +1,6 @@
 (ns cruncher.config)

-(def api {:host "http://0.0.0.0:5000/"
+(def api {:host "http://localhost:5000/"
           :init "api/init/"
           :base "api/"
           :login "api/login"


Bumped lambda-blog patch version.

Bumped lambda-blog patch version.

--- lambda-blog/project.clj
+++ lambda-blog/project.clj
@@ -1,4 +1,4 @@
-(defproject lambda-blog/lambda-blog "1.0.6"
+(defproject lambda-blog/lambda-blog "1.0.7"
   :description "A static blog generator."
   :url "https://github.com/Idorobots/lambda-blog"
   :license {:name "MIT License"


Trim namespace from the value passed to print-doc

Fixes an issue in which the namespace would appear twice when calling doc. If
the namespace on the :name symbol exists and is the same as the :ns symbol,
we drop the namespace value from the :name symbol before calling print-doc.

Related to CLJS-921, but the fix should not cause problems if ClojureScript's
behavior changes.

Signed-off-by: Mike Fikes <a17fed27eaa842282862ff7c1b9c8395a26ac320@fikesfarm.com>

--- planck-cljs/src/planck/core.cljs
+++ planck-cljs/src/planck/core.cljs
@@ -198,8 +198,11 @@
             doc (if (repl-specials (second expression-form))
                   (repl/print-doc (repl-special-doc (second expression-form)))
                   (repl/print-doc
-                    (let [sym (second expression-form)]
-                          (with-compiler-env st (resolve env sym))))))
+                    (let [sym (second expression-form)
+                          var (with-compiler-env st (resolve env sym))]
+                      (if (= (namespace (:name var)) (str (:ns var)))
+                        (update var :name #(symbol (name %)))
+                        var)))))
           (prn nil))
         (try
           (cljs/eval-str


Use transducers for local keyword completions

--- planck-cljs/src/planck/repl.cljs
+++ planck-cljs/src/planck/repl.cljs
@@ -480,10 +480,10 @@

 (defn- spec-registered-keywords
   [ns]
-  (->> (s/registry)
-    keys
+  (eduction
     (filter keyword?)
-    (filter #(= (str ns) (namespace %)))))
+    (filter #(= (str ns) (namespace %)))
+    (keys (s/registry))))

 (defn- local-keyword-str
   [kw]
@@ -497,10 +497,12 @@
 (defn- local-keyword-completions
   [buffer kw-name]
   (let [buffer-prefix (subs buffer 0 (- (count buffer) (count kw-name) 2))]
-    (clj->js (->> (spec-registered-keywords @current-ns)
-               (map local-keyword-str)
-               (filter #(string/starts-with? % (str "::" kw-name)))
-               (map #(str buffer-prefix %))))))
+    (clj->js (sequence
+               (comp
+                 (map local-keyword-str)
+                 (filter #(string/starts-with? % (str "::" kw-name)))
+                 (map #(str buffer-prefix %)))
+               (spec-registered-keywords @current-ns)))))

 (defn- ^:export get-completions
   [buffer]


unit test fix.

unit test fix.

--- test/metabase/models/dependency_test.clj
+++ test/metabase/models/dependency_test.clj
@@ -65,7 +65,7 @@
   #{}
   (do
     (update-dependencies Mock 2 {:test ["a" "b" "c"]})
-    (set (db/sel :many Dependency :model_id 2))))
+    (set (db/sel :many Dependency :model "Mock" :model_id 2))))

 ;; valid working dependencies list
 (expect


Always include a responses map, even if it is empty

--- src/io/aviso/rook/swagger.clj
+++ src/io/aviso/rook/swagger.clj
@@ -304,6 +304,9 @@
           (assoc-in % paths-key
                     (remove-nil-vals {:description  description
                                       :summary      summary
+                                      ;; This is required inside a Operation object:
+                                      :responses    {}
+                                      ;; This aligns very nicely with Rook:
                                       :operation-id (:function endpoint-meta)}))
           (path-params-injector swagger-options % routing-entry params-key)
           (query-params-injector swagger-options % routing-entry params-key)


Fix package paths.

Fix package paths.

--- test/src/clojure/neko/threading_test.clj
+++ test/src/clojure/neko/threading_test.clj
@@ -44,8 +44,8 @@
   (let [intent (doto (Intent.)
                  (.addCategory Intent/CATEGORY_LAUNCHER)
                  (.addFlags Intent/FLAG_ACTIVITY_NEW_TASK)
-                 (.setClassName "android_toolkit.test_app"
-                                "android_toolkit.test_app.TestActivity")
+                 (.setClassName "com.sattvik.neko.test_app"
+                                "com.sattvik.neko.test_app.TestActivity")
                  (.setAction Intent/ACTION_MAIN))]
     (reset! activity (.startActivity this intent nil nil))))


Delete congregation after test

Delete congregation after test

--- test/territory_bro/congregation_test.clj
+++ test/territory_bro/congregation_test.clj
@@ -69,6 +69,11 @@
     (.migrate tenant)
     id))

+(defn delete-congregations! [conn]
+  (doseq [congregation (jdbc/query conn ["select schema_name from congregation"])]
+    (jdbc/execute! conn [(str "drop schema " (:schema_name congregation) " cascade")]))
+  (jdbc/execute! conn ["delete from congregation"]))
+
 (deftest congregations-test
   (let [master (master-db-migrations "test_master")
         tenant (tenant-db-migrations "test_tenant")]
@@ -89,9 +94,9 @@
         (is (= [{:congregation_id id, :name "foo", :schema_name "foo_schema"}]
                (query conn :get-congregations)))
         (is (= [] (jdbc/query conn ["select * from foo_schema.territory"]))
-            "should create congregation schema"))))
+            "should create congregation schema")))
+    (delete-congregations! conn))

-  ;; TODO Remove test schemas
   (testing "lists congregations to which the user has access")
   (testing "hides congregations to which the user has no access")
   (testing "superadmin can access all congregations"))


preposition's argument's subcat is empty

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -280,7 +280,9 @@
        (let [object-semantics (atom :top)]
          {:synsem {:cat :prep
                    :subcat {:1 {:cat :noun
-                                :sem object-semantics}}
+                                :subcat '()
+                                :sem object-semantics}
+                            :2 '()}
                    :sem {:obj object-semantics}}}))
       ;; </preposition default rules>


improve comment

improve comment

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -226,7 +226,7 @@
        ;; remove the second argument and semantic object to make verbs intransitive,
        ;; if it is {:cat :verb} and {:allow-intransitive true}, etc.

-       ;; if condition:
+       ;; if verb allows intransitivization:
        {:allow-intransitivize true
         :synsem {:cat :verb
                  :aux false
@@ -234,7 +234,7 @@
                        :reflexive false}
                  :subcat {:2 {:cat :noun}
                           :3 []}}}
-       ;; then condition:
+       ;; then create new intransitive entry:
        (fn [lexeme]
          (unify (dissoc-paths lexeme [[:synsem :sem :obj]
                                       [:synsem :subcat :2]


Move details out of the track fn.

Move details out of the track fn.

--- src/kolmogorov_music/song.clj
+++ src/kolmogorov_music/song.clj
@@ -83,17 +83,17 @@
        (with (->> (phrase [8] [9]) (times 2)))
        (with (->> (phrase [1 1 2] [0 4 0]) (times 4)))
        (with (->> (phrase (cycle [2/3 1/3]) [8 8 nil 8 nil 8 nil 7]) (times 4)))
-       (wherever :pitch, :pitch scale/major)
+       (wherever :pitch, :pitch (comp scale/A scale/major scale/lower))
        code))

 (defn decode [channels notes]
   (decode* (vec (repeat channels 0)) notes))

-(defn track []
+(defn track [start]
   (->>
-    (champernowne/word 10 row)
+    (champernowne/word 10 start)
     (decode 4)
-    (wherever :pitch, :pitch (comp temperament/equal scale/A scale/lower))
+    (wherever :pitch, :pitch temperament/equal)
     (where :time (bpm 120))
     (where :duration (bpm 120))))

@@ -101,7 +101,7 @@

    ; Loop the track, allowing live editing.
   (live/stop)
-  (live/play (track))
+  (live/play (track row))
   (fx-reverb)
   (fx-chorus)
   (fx-distortion)


Revert "Add Twitter lexicon", as it's not very interesting.

This reverts commit 4e6705b3531fee9a85ae641d5bf9017d3c78cf0a.

--- src/kolmogorov_music/talk.clj
+++ src/kolmogorov_music/talk.clj
@@ -128,9 +128,9 @@
 (fact "Lexicons aren't very random."
   (randomness (take 10000 (library-of-babel))) => #(< % 1/100))

-(comment
-  (take 100000
-     (letfn[(t[](cons[](for[x(lazy-seq(t))e(map char(range 32 65536))](conj x e))))](map #(apply str %)(take-while #(<(count %)141)(t))))))
+
+
+

 ;;;;;;;;;;;;;;;;
 ;;; Contact ;;;;


Lower-case links in messages

Lower-case links in messages

--- src/braid/ui/views/message.cljs
+++ src/braid/ui/views/message.cljs
@@ -28,18 +28,19 @@
   {:urls
    {:pattern helpers/url-re
     :replace (fn [match]
-               [:a.external {:href match
-                             :title match
-                             :style {:background-color  (-> match
-                                                            helpers/url->parts
-                                                            :domain
-                                                            ->color)}
-                             :target "_blank"
-                             ; rel to address vuln caused by target=_blank
-                             ; https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
-                             :rel "noopener noreferrer"
-                             :tabIndex -1}
-                 (abridged-url match)])}
+               (let [url (string/lower-case match)]
+                 [:a.external {:href url
+                               :title url
+                               :style {:background-color  (-> url
+                                                              helpers/url->parts
+                                                              :domain
+                                                              ->color)}
+                               :target "_blank"
+                               ; rel to address vuln caused by target=_blank
+                               ; https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
+                               :rel "noopener noreferrer"
+                               :tabIndex -1}
+                  (abridged-url url)]))}
    :users
    {:pattern #"@([-0-9a-z]+)"
     :replace (fn [match]


Squelch logs in tests

Squelch logs in tests

--- test/com/farmlogs/conduit/subscription/ack_process_test.clj
+++ test/com/farmlogs/conduit/subscription/ack_process_test.clj
@@ -95,31 +95,32 @@
           should be terminated.")))

   (testing "Ack process keeps working if there's an exception in WorkerResult."
-    (let [input (a/chan 1)
-          ack-process (->ack-process input 1 nil)
-          output (a/chan 2) ;; Capture results sent to the msg broker
-          send-result (partial result output)
-          result-chan1 (a/chan 1)
-          result-chan2 (a/chan 1)]
+    (with-redefs [clojure.tools.logging/log* (constantly :no-op)]
+      (let [input (a/chan 1)
+           ack-process (->ack-process input 1 nil)
+           output (a/chan 2) ;; Capture results sent to the msg broker
+           send-result (partial result output)
+           result-chan1 (a/chan 1)
+           result-chan2 (a/chan 1)]

-      ;; Simulate the arrival of 2 messages
-      (a/>!! input [result-chan1 :foo])
-      (a/>!! input [result-chan2 :bar])
+       ;; Simulate the arrival of 2 messages
+       (a/>!! input [result-chan1 :foo])
+       (a/>!! input [result-chan2 :bar])

-      ;; Begin shutdown sequence for the ack-process
-      (a/close! input)
+       ;; Begin shutdown sequence for the ack-process
+       (a/close! input)

-      (is (= ::timeout (take-with-timeout ack-process 50))
-          "The ack-process should still be running, b/c there are
+       (is (= ::timeout (take-with-timeout ack-process 50))
+           "The ack-process should still be running, b/c there are
           unhandled messages.")

-      ;; Simulate a worker returning some sort of unexpected result.
-      (a/>!! result-chan2 (broken-result))
+       ;; Simulate a worker returning some sort of unexpected result.
+       (a/>!! result-chan2 (broken-result))

-      ;; Simulate a worker :ack'ing :foo
-      (a/>!! result-chan1 (send-result :ack))
-      (is (nil? (a/<!! ack-process))
-          "ack-process should be termainated.")
-      (a/close! output)
-      (is (= #{[:ack :foo]} (a/<!! (a/into #{} output)))
-          "The :foo message should be ACK'd."))))
+       ;; Simulate a worker :ack'ing :foo
+       (a/>!! result-chan1 (send-result :ack))
+       (is (nil? (a/<!! ack-process))
+           "ack-process should be termainated.")
+       (a/close! output)
+       (is (= #{[:ack :foo]} (a/<!! (a/into #{} output)))
+           "The :foo message should be ACK'd.")))))


[l.d.utils] Customizable sh output without *debug*

--- src/leiningen/droid/utils.clj
+++ src/leiningen/droid/utils.clj
@@ -209,8 +209,10 @@

 (defn get-sdk-android-jar
   "Returns a version-specific path to the `android.jar` SDK file."
-  [sdk-root version]
-  (str (file (get-sdk-platform-path sdk-root version) "android.jar")))
+  ([{{:keys [sdk-path target-version]} :android :as project}]
+   (get-sdk-android-jar sdk-path target-version))
+  ([sdk-root version]
+   (str (file (get-sdk-platform-path sdk-root version) "android.jar"))))

 (defn get-sdk-google-api-path
   "Returns a version-specific path to the Google SDK directory."
@@ -267,6 +269,10 @@
         mod-proj (assoc project :dependencies res-deps)]
     (resolve-dependencies :dependencies mod-proj)))

+(def ^:dynamic *sh-print-output*
+  "If true, print the output of the shell command regardless of *debug*."
+  false)
+
 (defmacro with-process
   "Executes the subprocess specified in the binding list and applies
   `body` do it while it is running. The binding list consists of a var
@@ -284,16 +290,17 @@
            _# (.redirectErrorStream builder# true)
            ~process-name (.start builder#)
            output# (line-seq (reader (.getInputStream ~process-name)))
-           out-stream# (StringWriter.)]
+           out-stream# (StringWriter.)
+           print-output?# (or *debug* *sh-print-output*)]
        ~@body
        (doseq [line# output#]
-         (if *debug*
-           (debug line#)
+         (if print-output?#
+           (info line#)
            (binding [*out* out-stream#]
              (println line#))))
        (.waitFor ~process-name)
        (when-not (and (= (.exitValue ~process-name) 0)
-                      (not *debug*))
+                      (not print-output?#))
          (info (str out-stream#)))
        (when-not (= (.exitValue ~process-name) 0)
          (abort "Abort execution."))


Fix config components teardown

Fix config components teardown

--- src/clj/comic_reader/config.clj
+++ src/clj/comic_reader/config.clj
@@ -15,7 +15,8 @@
            :database-uri (env :database-uri)
            :norms-dir    (env :norms-dir)))

-  (stop [component])
+  (stop [component]
+    component)

   PConfig
   (database-uri [cfg] (:database-uri cfg))


Correct server shutdown logic

Correct server shutdown logic

--- src/clj/comic_reader/server.clj
+++ src/clj/comic_reader/server.clj
@@ -18,16 +18,18 @@
                                    :join? false})))))

   (stop [component]
-    (if (not server)
+    (if-not server
       component
       (do
-        (when (or (not (.isStopped server))
-                  (not (.isStopping server)))
+        (when-not (or (.isStopped server)
+                      (.isStopping server))
           (println ";; Shutting down web server...")
           (.stop server))
-        (assoc component
-               :web-app nil
-               :server nil)))))
+        (if (.isStopped server)
+          (assoc component
+                 :web-app nil
+                 :server nil)
+          component)))))

 (defn new-server [port]
   (map->WebServer {:port port}))


async container creation

async container creation

--- src/clj/dokkaa_builder/apps.clj
+++ src/clj/dokkaa_builder/apps.clj
@@ -51,27 +51,39 @@
   (let [app (wcar* (redis/get (str "apps:" app-name)))]
     (:instances app)))

+(defn future-create-instance [cli host-port image & {:keys [port tag command]}]
+  (future
+    (let [id (docker/run cli image
+               :tag tag
+               :cmd command
+               :port-bindings {host-port port})
+          upstream (upstream-url cli host-port)]
+      {:id id, :host upstream})))
+
 (defn create [app-name user image & {:keys [tag command port ps]}]
   (let [ps (or ps 1)
         backends (pick-backends ps)
         front-url (default-frontend-url app-name)
         old-isntances (instances app-name)
-        new-instances (vec (for [{cli :client host-port :port} backends]
-                             (let [id (docker/run cli image
-                                        :tag tag
-                                        :cmd command
-                                        :port-bindings {host-port port})
-                                   upstream (upstream-url cli host-port)]
-                               {:id id, :host upstream})))]
-    (when old-isntances (router/delete-domain front-url))
-    (apply router/add-domain front-url (map :host new-instances))
-    (set-app app-name {:image      image
-                       :tag        tag
-                       :user-id    (:id user)
-                       :front-urls [front-url]
-                       :instances  new-instances})
-    (when old-isntances (delete-instances old-isntances))
-    nil))
+        app {:status  :creating
+             :image   image
+             :tag     tag
+             :user-id (:id user)}]
+    (set-app app-name app)
+    (future
+      (let [futures (doall (for [{cli :client host-port :port} backends]
+                             (future-create-instance cli host-port image
+                                                     :port port
+                                                     :tag tag
+                                                     :command command)))
+            new-instances (mapv deref futures)]
+      (when old-isntances (router/delete-domain front-url))
+      (apply router/add-domain front-url (map :host new-instances))
+      (set-app app-name (merge app {:status :running
+                                    :front-urls [front-url]
+                                    :instances  new-instances}))
+      (when old-isntances (delete-instances old-isntances))))
+    app))

 (defn update [req]
   )


component spec improved to generate actual data

--- src/clj/hellhound/component.clj
+++ src/clj/hellhound/component.clj
@@ -1,5 +1,6 @@
 (ns hellhound.component
-  (:require [clojure.spec.alpha :as s])
+  (:require [clojure.spec.alpha :as s]
+            [clojure.spec.gen.alpha :as gen])
   (:import (clojure.lang PersistentArrayMap)))

@@ -37,19 +38,35 @@
     (::name this))

   (dependencies [this]
-    (::depends-on this)))
+     (::depends-on this)))

-(s/def ::name keyword?)
+(s/def ::name qualified-keyword?)
 (s/def ::start-fn (s/fspec :args (s/cat :this map? :context map?)
                            :ret map?
-                           :fn #(= (get-name (:ret %))
-                                   (get-name (:this (:args %))))))
+                           :fn #(= (::name (:ret %))
+                                   (::name (:this (:args %))))))

 (s/def ::stop-fn (s/fspec :args (s/cat :this map? :context map?)
                           :ret map?
-                          :fn #(= (get-name (:ret %))
-                                  (get-name (:this (:args %))))))
+                          :fn #(= (::name (:ret %))
+                                  (::name (:this (:args %))))))

-(s/def ::component (s/and #(satisfies? IComponent)
-                          (s/keys :req [::name ::start-fn ::stop-fn])))
+(s/def ::depends-on (s/coll-of keyword? :kind vector? :distinct true))
+(s/def ::component (s/keys :req [::name ::start-fn ::stop-fn]
+                           :opt [::depends-on]))
+
+
+(gen/sample (s/gen ::name))
+(gen/sample (s/gen ::start-fn))
+(gen/sample (s/gen ::component))
+a
+(get-name a)
+(started? a)
+(dependencies a)
+(start! a {})
+(keyword-ns? ::name)
+(s/gen ::name)
+(gen/sample (gen/list gen/boolean))
+
+(gen/sample (gen/vector gen/keyword))


Make the pipeline2 client code emit proper (namespaced) xml

--- src/clj/mdr2/pipeline2/core.clj
+++ src/clj/mdr2/pipeline2/core.clj
@@ -1,19 +1,25 @@
 (ns mdr2.pipeline2.core
   "Thin layer on top of the [Pipeline2 Web Service
-  API](https://code.google.com/p/daisy-pipeline/wiki/WebServiceAPI)"
-  (:require [clojure.data.xml :as xml]
+  API](https://daisy.github.io/pipeline/WebServiceAPI)"
+  (:require [clj-http.client :as client]
+            [clj-http.util :refer [url-encode]]
+            [clojure.data.codec.base64 :as b64]
+            [clojure.data.xml :as xml]
+            [clojure.data.zip :as zf]
+            [clojure.data.zip.xml :refer [attr xml-> xml1->]]
+            [clojure.java.io :as io]
+            [clojure.zip :refer [xml-zip]]
+            [crypto.random :as crypt-rand]
             [java-time :as time]
-            [pandect.core :as pandect]
-            [clojure.data.codec.base64 :as b64]
-            [crypto.random :as crypt-rand]
-            [clj-http.client :as client]
-            [clj-http.util :refer [url-encode]]))
+            [mdr2.config :refer [env]]
+            [pandect.algo.sha1 :as pandect]
+            [clojure.tools.logging :as log])
+  (:import [java.util.zip ZipEntry ZipOutputStream]))

 (def ws-url "http://localhost:8181/ws")

-(def ^:private auth-id "clientid")
-(def ^:private secret "supersekret")
-(def ^:private remote false)
+(def ^:private timeout 1000)
+(def ^:private poll-interval 3000)

 (defn- create-hash [message signing-key]
   (-> (pandect/sha1-hmac-bytes message signing-key)
@@ -21,30 +27,33 @@
       String.))

 (defn auth-query-params [uri]
-  (let [timestamp (str (time/local-date-time))
+  (let [timestamp (time/format :iso-local-date-time (time/local-date-time))
         nonce (crypt-rand/base64 32)
+        auth-id (env :pipeline2-auth-id)
         params {"authid" auth-id "time" timestamp "nonce" nonce}
         query-string (str uri "?" (client/generate-query-string params))
-        hashcode (create-hash query-string secret)]
+        hashcode (create-hash query-string (env :pipeline2-secret))]
     {:query-params
      {"authid" auth-id "time" timestamp "nonce" nonce "sign" hashcode}}))

+(def qname (partial xml/qname "http://www.daisy.org/ns/pipeline/data"))
+
 (defn job-sexp [script inputs options]
-  (let [script-url (str ws-url "/script/" script)]
-    [:jobRequest {:xmlns "http://www.daisy.org/ns/pipeline/data"}
-     [:script {:href script-url}]
+  (let [script-url (str ws-url "/scripts/" script)]
+    [(qname "jobRequest")
+     [(qname "script") {:href script-url}]
      (for [[port file] inputs]
-       [:input {:name (name port)}
-        [:item {:value (str "file:" (url-encode file))}]])
+       [(qname "input") {:name (name port)}
+        [(qname "item") {:value (if-not (env :pipeline2-remote)
+                         (str "file:" (url-encode file))
+                         (url-encode (.getName (io/file file))))}]])
      (for [[key value] options]
-       [:option {:name (name key)} value])]))
+       [(qname "option") {:name (name key)} value])]))

 (defn job-request [script inputs options]
   (-> (job-sexp script inputs options)
       xml/sexp-as-element
       xml/emit-str))
-
-(defn wait [job])

 (defn jobs []
   (let [url (str ws-url "/jobs")
@@ -52,18 +61,38 @@
     (when (client/success? response)
       (-> response :body xml/parse-str))))

-(defn job [id]
+(defn get-job [id]
   (let [url (str ws-url "/jobs/" id)
-        response (client/get url (auth-query-params url))]
+        response (client/get url (merge (auth-query-params url)
+                                        #_{:socket-timeout timeout :conn-timeout timeout}))]
     (when (client/success? response)
       (-> response :body xml/parse-str))))
+
+(defn- zip-files [files]
+  (let [tmp-name (.getAbsolutePath (java.io.File/createTempFile "pipeline2-client" ".zip"))]
+    (with-open [zip (ZipOutputStream. (io/output-stream tmp-name))]
+      (doseq [f (map io/file files)]
+        (.putNextEntry zip (ZipEntry. (.getName f)))
+        (io/copy f zip)
+        (.closeEntry zip)))
+    tmp-name))
+
+(defn- multipart-request [inputs body]
+  {:multipart
+   [{:name "job-data" :content (io/file (zip-files (vals inputs)))}
+    {:name "job-request" :content body}]})
+
+(defn- maybe-multipart [inputs body]
+  (if (empty? inputs) body (multipart-request inputs body)))

 (defn job-create [script inputs options]
   (let [url (str ws-url "/jobs")
         request (job-request script inputs options)
         auth (auth-query-params url)
         body {:body request}
-        response (client/post url (merge auth body))]
+        multipart (maybe-multipart inputs request)
+        ;;response (client/post url (merge multipart auth))]
+        response (client/post url (merge body auth))]
     (when (client/success? response)
       (-> response :body xml/parse-str))))


test for Port Anson Grid

test for Port Anson Grid

--- src/clj/test/cards-upgrades.clj
+++ src/clj/test/cards-upgrades.clj
@@ -219,6 +219,29 @@
       (prompt-choice :runner "OK")
       (is (= 0 (count (:scored (get-runner)))) "No scored agendas"))))

+(deftest port-anson-grid
+  "Port Anson Grid - Prevent the Runner from jacking out until they trash a program"
+  (do-game
+    (new-game (default-corp [(qty "Port Anson Grid" 1) (qty "Data Raven" 1)])
+              (default-runner [(qty "Faerie" 1) (qty "Technical Writer" 1)]))
+    (play-from-hand state :corp "Port Anson Grid" "New remote")
+    (play-from-hand state :corp "Data Raven" "Server 1")
+    (take-credits state :corp)
+    (play-from-hand state :runner "Technical Writer")
+    (play-from-hand state :runner "Faerie")
+    (let [pag (get-content state :remote1 0)
+          fae (get-in @state [:runner :rig :program 0])
+          tw (get-in @state [:runner :rig :resource 0])]
+      (run-on state "Server 1")
+      (core/rez state :corp pag)
+      (is (:cannot-jack-out (get-in @state [:run])) "Jack out disabled for Runner") ; UI button greyed out
+      (core/trash state :runner tw)
+      (is (:cannot-jack-out (get-in @state [:run])) "Resource trash didn't disable jack out prevention")
+      (core/trash state :runner fae)
+      (is (nil? (:cannot-jack-out (get-in @state [:run]))) "Jack out enabled by program trash")
+      (run-on state "Server 1")
+      (is (:cannot-jack-out (get-in @state [:run])) "Prevents jack out when upgrade is rezzed prior to run"))))
+
 (deftest product-placement
   "Product Placement - Gain 2 credits when Runner accesses it"
   (do-game


get dimension size from opt

get dimension size from opt

--- src/cljs/searchbot/parsets.cljs
+++ src/cljs/searchbot/parsets.cljs
@@ -127,7 +127,7 @@
                  :url url
                  :parsets-agg (->> agg :terms (map keyword))
                  :get-agg-terms #(:parsets-agg (om/get-state owner))
-                 :size (get-in opts [:dimensions :size])
+                 :size (or (get-in opts [:dimensions :size]) 5)
                  :make-agg-query #(->query {:agg-terms ((:get-agg-terms (om/get-state owner)))
                                             :sub-aggs (:sub agg)
                                             :size (:size (om/get-state owner))


Small change.

Small change.

--- src/cljs/tackytoe/app/game.cljs
+++ src/cljs/tackytoe/app/game.cljs
@@ -3,9 +3,14 @@
 (def players [{:name "Rajnikanth" :email "r@k.com"}
               {:name "Rakhi" :email "foo@bar.com"}])

+(defn player
+  [name email]
+  [:li [:a {:href (str "mailto:" email) :target :_blank}
+        name]])
+
+
 (defn game []
   [:div "This is the tic tac toe game page."
-   [:ul (for [p players]
-          [:li [:a {:href (str "mailto:" (:email p)) :target :_blank}
-                (:name p)]])]
+   [:ul (for [{:keys [name email]} players]
+          [player name email])]
    [:div [:a {:href "#/"} "go to the home page"]]])


Simplify and typehint functions

Simplify and typehint functions

--- src/clojure/flambo/function.clj
+++ src/clojure/flambo/function.clj
@@ -1,7 +1,22 @@
 (ns flambo.function
   (:require [serializable.fn :as sfn]
             [flambo.kryo :as kryo]
-            [flambo.cache :as cache]))
+            [flambo.cache :as cache])
+  (:import [org.apache.spark.api.java.function
+            Function
+            Function2
+            Function3
+            VoidFunction
+            VoidFunction2
+            FlatMapFunction
+            FlatMapFunction2
+            PairFlatMapFunction
+            PairFunction
+            DoubleFunction
+            DoubleFlatMapFunction
+            MapFunction
+            ReduceFunction
+            FilterFunction]))

 (defn- serfn? [f]
   (= (type f) :serializable.fn/serializable-fn))
@@ -26,6 +41,9 @@
   [fmt sym-name]
   (symbol (format fmt sym-name)))

+(defn check-not-nil! [x message]
+  (when (nil? x) (throw (ex-info message))))
+
 (defmacro gen-function
   [clazz wrapper-name]
   (let [new-class-sym (mk-sym "flambo.function.%s" clazz)
@@ -42,23 +60,19 @@
        (def ~(mk-sym "%s-init" clazz) -init)
        (defn ~(mk-sym "%s-call" clazz)
          [~(vary-meta 'this assoc :tag new-class-sym) & ~'xs]
-         (if-not ~'this
-           (throw (ex-info "Nil this func instance" {})))
-         (if-not ~'xs
-           (throw (ex-info "Nil xs args" {})))
+         (check-not-nil! ~'this "Nil this func instance")
+         (check-not-nil! ~'xs "Nil xs args")
          (let [fn-or-serfn# (.state ~'this)
-               _# (if-not fn-or-serfn#
-                    (throw (ex-info "Nil fn-or-serfn state")))
+               _# (check-not-nil! "Nil fn-or-serfn state")
                f# (if (instance? array-of-bytes-type fn-or-serfn#)
                     (binding [sfn/*deserialize* kryo/deserialize]
                       (deserialize-fn fn-or-serfn#))
                     fn-or-serfn#)]
-           (if-not f#
-             (throw (ex-info "Nil func or serialize func")))
+           (check-not-nil! f# "Nil func or serialize func")
            (apply f# ~'xs)))
-       (defn ~wrapper-name [f#]
-         (if-not f#
-           (throw (ex-info "Nil func or serialize func wrapper")))
+       (defn ~(vary-meta wrapper-name assoc :tag clazz)
+         [f#]
+         (check-not-nil! "Nil func or serialize func wrapper")
          (new ~new-class-sym
               (if (serfn? f#)
                 (binding [sfn/*serialize* kryo/serialize]


Support :gravity attribute in LinearLayout

--- src/clojure/neko/ui/mapping.clj
+++ src/clojure/neko/ui/mapping.clj
@@ -38,7 +38,9 @@
              :inherits :text-view
              :attributes {:text "Default button"}}
     :linear-layout {:classname android.widget.LinearLayout
-                    :inherits :view-group}
+                    :inherits :view-group
+                    :value-namespaces
+                    {:gravity android.view.Gravity}}
     :relative-layout {:classname android.widget.RelativeLayout
                       :inherits :view-group}
     :edit-text {:classname android.widget.EditText


Added link to issues

Added link to issues

--- src/clojure/staircase/views.clj
+++ src/clojure/staircase/views.clj
@@ -11,6 +11,8 @@
   [tag (assoc attrs :charset "utf-8")])

 (def ^:dynamic require-js "/vendor/requirejs/require.js")
+
+(def repo "https://github.com/alexkalderimis/staircase")

 (defn- entry-point [ep]
   (->> (include-js require-js)
@@ -96,9 +98,12 @@
                               [:span
                                [:i.fa.fa-envelope-o]
                                " Contact"])
-                     (link-to "https://github.com/alexkalderimis/staircase"
+                     (link-to repo
                               [:i.fa.fa-github]
-                              " View on github")])]
+                              " View on github")
+                     (link-to (str repo "/issues")
+                              [:i.fa.fa-warning]
+                              " Report a problem")])]
    [:li {:ng-show "auth.loggedIn"} (logout)]
    [:li {:ng-hide "auth.loggedIn"} (login)]
    ])


refined extent

refined extent

--- configuration/xml-input-extent.clj
+++ configuration/xml-input-extent.clj
@@ -1,3 +1,6 @@
+;TODO Extensions, Ew poprawienie mapowań blokowych - w tym przypadku można np. wywalić mapowania kontenerów - nie są raczej w ogóle potrzebne,
+;zrobić ich mapowanie poprzez ścieżko docelowe
+
 (for [:glue:Domains :AdminDomain]
   (add-instance :AdminDomain
                 (mapping [:Distributed :Distributed-text-node] :Distributed)
@@ -55,3 +58,186 @@
                 (mapping [:UserManager-text-node] :UserManager)
                 (mapping [:Member-text-node] :Member)))

+;????????????????
+(for [:glue:Domains :AdminDomain :Services]
+  (add-instance :Services
+    (mapping [:Service :Service-text-node] :Service)
+    (mapping [:ComputingService :ComputingService-text-node] :ComputingService)))
+
+(for [:glue:Domains :AdminDomain :Services :Service]
+  (add-instance :Service
+    (mapping [:ID :ID-text-node] :ID)
+    (mapping [:Name :Name-text-node] :Name)
+    (mapping [:Capability :Capability-text-node] :Capability)
+    (mapping [:Type :Type-text-node] :Type)
+    (mapping [:QualityLevel :QualityLevel-text-node] :QualityLevel)
+    (mapping [:Complexity :Complexity-text-node] :Complexity)
+    (mapping [:StatusPage] :StatusPage)))
+
+(for [:glue:Domains :AdminDomain :Services :Service :Location]
+  (add-instance :Location
+    (mapping [:Distributed :Distributed-text-node] :Distributed)
+    (mapping [:Owner :Owner-text-node] :Owner)
+    (mapping [:WWW :WWW-text-node] :WWW)
+    (mapping [:Description :Description-text-node] :Description)
+    (mapping [:LocalID :LocalID-text-node :ID] :ID)
+    (mapping [:Name :Name-text-node] :Name)
+    (mapping [:OtherInfo :OtherInfo-text-node] :OtherInfo)
+    (mapping [:Latitude-attribute] :Latitude)
+    (mapping [:Longitude-attribute] :Longitude)
+    (mapping [:PostCode-attribute] :PostCode)
+    (mapping [:Country-attribute] :Country)
+    (mapping [:Place-attribute] :Place)
+    (mapping [:Address-attribute] :Address)))
+
+(for [:glue:Domains :AdminDomain :Services :Service :Contact]
+  (add-instance :Contact
+    (mapping [:Distributed :Distributed-text-node] :Distributed)
+    (mapping [:Owner :Owner-text-node] :Owner)
+    (mapping [:WWW :WWW-text-node] :WWW)
+    (mapping [:Description :Description-text-node] :Description)
+    (mapping [:LocalID :LocalID-text-node :ID] :ID)
+    (mapping [:Name :Name-text-node] :Name)
+    (mapping [:OtherInfo :OtherInfo-text-node] :OtherInfo)
+    (mapping [:Latitude-attribute] :Latitude)
+    (mapping [:Longitude-attribute] :Longitude)
+    (mapping [:PostCode-attribute] :PostCode)
+    (mapping [:Country-attribute] :Country)
+    (mapping [:CreationTime-attribute] :CreationTime)
+    (mapping [:Validity-attribute] :Validity)))
+
+(for [:glue:Domains :AdminDomain :Services :Service :Endpoint]
+  (add-instance :Endpoint
+    (mapping [:ID :ID-text-node] :ID)
+    (mapping [:URL :URL-text-node] :URL)
+    (mapping [:Capability :Capability-text-node] :Capability)
+    (mapping [:Technology :Technology-text-node] :Technology)
+    (mapping [:Interface :Interface-text-node] :Interface)
+    (mapping [:WSDL :WSDL-text-node] :WSDL)
+    (mapping [:SupportedProfile :SupportedProfile-text-node] :SupportedProfile)
+    (mapping [:Semantics :Semantics-text-node] :Semantics)
+    (mapping [:Implementor :Implementor-text-node] :Implementor)
+    (mapping [:ImplementationName :ImplementationName-text-node] :ImplementationName)
+    (mapping [:QualityLevel :QualityLevel-text-node] :QualityLevel)
+    (mapping [:HealthState :HealthState-text-node] :HealthState)
+    (mapping [:HealthStateInfo :HealthStateInfo-text-node] :HealthStateInfo)
+    (mapping [:ServingState :ServingState-text-node] :ServingState)
+    (mapping [:StartTime :StartTime-text-node] :StartTime)
+    (mapping [:IssuerCA :IssuerCA-text-node] :IssuerCA)
+    (mapping [:TrustedCA :TrustedCA-text-node] :TrustedCA)
+    (mapping [:DowntimeAnnounce :DowntimeAnnounce-text-node] :DowntimeAnnounce)
+    (mapping [:DowntimeStart :DowntimeStart-text-node] :DowntimeStart)
+    (mapping [:DowntimeEnd :DowntimeEnd-text-node] :DowntimeEnd)
+    (mapping [:DowntimeInfo :DowntimeInfo-text-node] :DowntimeInfo)))
+
+(for [:glue:Domains :AdminDomain :Services :Service :Endpoint :AccessPolicy]
+  (add-instance :AccessPolicy
+    (mapping [:CreationTime-attribute] :CreationTime)
+    (mapping [:Validity-attribute] :Validity)
+    (mapping [:LocalID :LocalID-text-node] :LocalID)
+    (mapping [:Scheme :Scheme-text-node] :Scheme)
+    (mapping [:Rule-text-node :Rule] :Rule)))
+
+(for [:glue:Domains :AdminDomain :Services :Service :Activities]
+  (add-instance :Activities
+    (mapping [:Activity] :Activity)))
+
+(for [:glue:Domains :AdminDomain :Services :Service :Activities :Activity]
+  (add-instance :Activity
+    (mapping [:ID :ID-text-node] :ID)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService]
+  (add-instance :ComputingService
+    (mapping [:ID :ID-text-node] :ID)
+    (mapping [:Name :Name-text-node] :Name)
+    (mapping [:Capability :Capability-text-node] :Capability)
+    (mapping [:Type :Type-text-node] :Type)
+    (mapping [:QualityLevel :QualityLevel-text-node] :QualityLevel)
+    (mapping [:Complexity :Complexity-text-node] :Complexity)
+    (mapping [:StatusPage] :StatusPage)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :Location]
+  (add-instance :Location
+    (mapping [:Distributed :Distributed-text-node] :Distributed)
+    (mapping [:Owner :Owner-text-node] :Owner)
+    (mapping [:WWW :WWW-text-node] :WWW)
+    (mapping [:Description :Description-text-node] :Description)
+    (mapping [:LocalID :LocalID-text-node :ID] :ID)
+    (mapping [:Name :Name-text-node] :Name)
+    (mapping [:OtherInfo :OtherInfo-text-node] :OtherInfo)
+    (mapping [:Latitude-attribute] :Latitude)
+    (mapping [:Longitude-attribute] :Longitude)
+    (mapping [:PostCode-attribute] :PostCode)
+    (mapping [:Country-attribute] :Country)
+    (mapping [:Place-attribute] :Place)
+    (mapping [:Address-attribute] :Address)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :Contact]
+  (add-instance :Contact
+    (mapping [:Distributed :Distributed-text-node] :Distributed)
+    (mapping [:Owner :Owner-text-node] :Owner)
+    (mapping [:WWW :WWW-text-node] :WWW)
+    (mapping [:Description :Description-text-node] :Description)
+    (mapping [:LocalID :LocalID-text-node :ID] :ID)
+    (mapping [:Name :Name-text-node] :Name)
+    (mapping [:OtherInfo :OtherInfo-text-node] :OtherInfo)
+    (mapping [:Latitude-attribute] :Latitude)
+    (mapping [:Longitude-attribute] :Longitude)
+    (mapping [:PostCode-attribute] :PostCode)
+    (mapping [:Country-attribute] :Country)
+    (mapping [:CreationTime-attribute] :CreationTime)
+    (mapping [:Validity-attribute] :Validity)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :ComputingEndpoint]
+  (add-instance :ComputingEndpoint
+    (mapping [:ID :ID-text-node] :ID)
+    (mapping [:URL :URL-text-node] :URL)
+    (mapping [:Capability :Capability-text-node] :Capability)
+    (mapping [:Technology :Technology-text-node] :Technology)
+    (mapping [:Interface :Interface-text-node] :Interface)
+    (mapping [:WSDL :WSDL-text-node] :WSDL)
+    (mapping [:SupportedProfile :SupportedProfile-text-node] :SupportedProfile)
+    (mapping [:Semantics :Semantics-text-node] :Semantics)
+    (mapping [:Implementor :Implementor-text-node] :Implementor)
+    (mapping [:ImplementationName :ImplementationName-text-node] :ImplementationName)
+    (mapping [:QualityLevel :QualityLevel-text-node] :QualityLevel)
+    (mapping [:HealthState :HealthState-text-node] :HealthState)
+    (mapping [:HealthStateInfo :HealthStateInfo-text-node] :HealthStateInfo)
+    (mapping [:ServingState :ServingState-text-node] :ServingState)
+    (mapping [:StartTime :StartTime-text-node] :StartTime)
+    (mapping [:IssuerCA :IssuerCA-text-node] :IssuerCA)
+    (mapping [:TrustedCA :TrustedCA-text-node] :TrustedCA)
+    (mapping [:DowntimeAnnounce :DowntimeAnnounce-text-node] :DowntimeAnnounce)
+    (mapping [:DowntimeStart :DowntimeStart-text-node] :DowntimeStart)
+    (mapping [:DowntimeEnd :DowntimeEnd-text-node] :DowntimeEnd)
+    (mapping [:DowntimeInfo :DowntimeInfo-text-node] :DowntimeInfo)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :ComputingEndpoint :AccessPolicy]
+  (add-instance :AccessPolicy
+    (mapping [:CreationTime-attribute] :CreationTime)
+    (mapping [:Validity-attribute] :Validity)
+    (mapping [:LocalID :LocalID-text-node] :LocalID)
+    (mapping [:Scheme :Scheme-text-node] :Scheme)
+    (mapping [:Rule-text-node :Rule] :Rule)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :ComputingActivitites]
+  (add-instance :ComputingActivitites
+    (mapping [:ComputingActivitiy] :ComputingActivitiy)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :ComputingActivitites :ComputingActivitiy]
+  (add-instance :ComputingActivitiy
+    (mapping [:ComputingActivityID :ComputingActivityID-text-node] :ComputingActivityID)))
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :ComputingShares]
+  (add-instance :ComputingShares
+    (mapping [:ComputingShares] :ComputingShares)))
+
+
+(for [:glue:Domains :AdminDomain :Services :ComputingService :ComputingShares :ComputingShare]
+  (add-instance :ComputingShare
+    (mapping [:LocalID :LocalID-text-node] :LocalID)
+    (mapping [:Description] :Description)
+    (mapping [:MappingQueue :MappingQueue-text-node] :MappingQueue)
+    (mapping [:MaxWallTime :MaxWallTime-text-node] :MaxWallTime)
+    (mapping [:MaxTotalWallTime :MaxTotalWallTime-text-node] :MaxTotalWallTime-text-node)
+    (maping [:ServingState :ServingState-text-node] :ServingState)))


Turn down product-join even more

Turn down product-join even more

--- test/aurora/btree_test.cljs
+++ test/aurora/btree_test.cljs
@@ -78,13 +78,13 @@
   (aurora.btree/self-join-prop 3))

 (defspec product-join-prop-test
-  1000
+  500
   (aurora.btree/product-join-prop 1))

 (defspec product-join-prop-test
-  1000
+  500
   (aurora.btree/product-join-prop 2))

 (defspec product-join-prop-test
-  1000
+  500
   (aurora.btree/product-join-prop 3))


fix test and make it more resemble actual usage of raeder/generate-question-and-correct-set

--- test/babel/test/reader.cljc
+++ test/babel/test/reader.cljc
@@ -2,39 +2,39 @@
   (:require [babel.reader :as reader]
             [babel.test.test :as btest]
             [clojure.pprint :refer [pprint]]
-            [dag_unify.core :as unify]
+            [dag_unify.core :as u]
             #?(:clj [clojure.test :as realtest :refer [deftest is]])
             #?(:clj [clojure.test :as realtest :refer [deftest is]])))

 (btest/init-db)

 (deftest chiamarsi
-  (let [generated
-        (reader/generate-question-and-correct-set
-         {:root {:italiano {:italiano "chiamarsi"}}
-          :synsem {:sem {:tense :present
-                         :aspect :simple}}
-          :comp {:synsem {:agr {:number :plur
-                                :person :3rd}}}}
-         "en"
-         "US"
-         "it"
-         "IT"
-
-         (fn [lexeme]
-           (or (and (= :verb (unify/get-in lexeme
-                                           [:synsem :cat]))
-                    (or (= [] (unify/get-in lexeme
-                                            [:synsem :subcat :2]))
-                        (= true (unify/get-in lexeme [:synsem :aux]))
-                        (= true (unify/get-in lexeme [:synsem :sem :reflexive]))))
-               (and (= :noun (unify/get-in lexeme
-                                           [:synsem :cat]))
-                    (= false (unify/get-in lexeme
-                                           [:synsem :sem :city] false))))))]
-
+  (let [target-grammar-rules
+        #{"s-present-phrasal"
+          "vp-32"
+          "vp-pronoun-phrasal"}
+        source-grammar-rules
+        #{"sentence-phrasal-head"
+          "transitive-vp-nonphrasal-head"
+          "transitive-vp-phrasal-head"
+          "noun-phrase"}
+
+        generated
+        (binding [babel.reader/target-grammar-subset target-grammar-rules
+                  babel.reader/source-grammar-subset source-grammar-rules]
+          (reader/generate-question-and-correct-set
+            {:root {:italiano {:italiano "chiamarsi"}}
+             :synsem {:sem {:tense :present
+                            :aspect :simple}}
+             :comp {:synsem {:agr {:number :plur
+                                   :person :3rd}}}}
+            "en"
+            "US"
+            "it"
+            "IT"))]
     (is (map? generated))
-    (is (not (nil? (:source generated))))))
+    (is (not (nil? (:source generated))))
+    (is (not (empty? (:targets generated))))))


create a game world context to track state in the world, even though that's anti-clojurey

--- src-cljs/hello.cljs
+++ src-cljs/hello.cljs
@@ -10,6 +10,12 @@
     (.appendChild js/document.body canvas)
     (.getContext canvas "2d")))

+(defn create-world []
+  (js-obj "bar" "baz"))
+
+(defn update [game-world]
+  (.log js/console "update"))
+
 (defn clear-for-frame [graphics-context]
   (let [canvas (aget graphics-context "canvas")
         width (aget canvas "width")
@@ -21,8 +27,10 @@
   (.fillRect graphics-context 10 20 200 100))

 (defn ^:export main []
-  (let [graphics-context (create-canvas)]
+  (let [graphics-context (create-canvas)
+        game-world (create-world)]
     (letfn [(anim-frame []
-              (render graphics-context)
-              (.requestAnimationFrame js/window anim-frame))] m .
+              (update game-world)
+              (render graphics-context game-world)
+              (.requestAnimationFrame js/window anim-frame))]
       (anim-frame))))


begin review

begin review

--- resources/workshop/do-things.clj
+++ resources/workshop/do-things.clj
@@ -14,12 +14,7 @@
 "Faire des choses: un cours Clojure crash

 Il est temps de savoir comment effectivement faire des choses avec Clojure! Hot Damn!
-
-Alors que vous avez sans doute entendu parler de l'appui de concurrence génial de Clojure et d'autres caractéristiques prodigieuses, caractéristique la plus saillante de Clojure est que ce est un Lisp. Dans ce chapitre, vous allez découvrir les éléments qui composent ce noyau Lisp: syntaxe, les fonctions et données. Cela vous donnera une base solide pour représenter et résoudre des problèmes dans Clojure.
-
-Ce travail de fond vous permettra également d'écrire du code super important. Dans la dernière section, vous allez lier le tout en créant un modèle d'un hobbit et écrire une fonction pour frapper dans un endroit aléatoire. Super! Important!
-
-Comme vous passez par le chapitre, je recommande que vous tapez les exemples dans un REPL et de les exécuter. Programmation dans une nouvelle langue est une compétence, et, tout comme yodel ou la natation synchronisée, vous devez pratiquer l'apprendre. Par ailleurs, \"Natation synchronisée pour yodelers pour les braves et True\" est due à être publié en Août 20never. Vérifiez-le!"
+"

@@ -33,9 +28,9 @@

 "Tout le code Clojure est écrit dans une structure uniforme. Clojure comprend:

-* Représentations littérales de structures de données comme les numéros, cordes, maps, et vecteurs
+* Représentations littérales de structures de données comme les nombres, Strings, maps, et vecteurs
 * Opérations
-Nous utilisons la forme de terme pour se référer au code structurellement valide. Ces représentations littérales sont des formes toutes valides:
+Nous utilisons le terme **form** pour se référer au code structurellement valide. Ces représentations littérales sont des form toutes valides:

 "
 (comment
@@ -45,13 +40,14 @@

   )

-"Votre code contiendra rarement littéraux flottants, bien sûr, car ils ne *font* rien de leur propre chef. Au lieu de cela, vous allez utiliser des littéraux dans les opérations. Les opérations sont la façon dont vous *faites les choses*. Toutes les opérations prennent la forme, \"ouverture parthensis, opérateur, opérandes, parenthèse fermante\":"
+"Votre code contiendra rarement de littéraux flottants, bien sûr, car ils ne font rien de leur propre chef. Au lieu de cela, vous allez utiliser des littéraux dans les opérations.
+Les opérations sont la façon dont vous *faites les choses*. Toutes les opérations prennent la forme, \"parenthèse ouverte, opérateur, opérandes, parenthèse fermante\":"
 (comment

   (operator operand1 operand2 ... operandn)
   )

-"Notez qu'il n'y a pas de virgules. Clojure utilise espaces pour séparer opérandes et il traite des virgules comme espaces. Voici quelques opérations d'exemple:"
+"Notez qu'il n'y a pas de virgules. Clojure utilise espaces pour séparer opérandes et il traite des virgules comme des espaces. Voici quelques opérations d'exemple:"
 (comment

   (+ 1 2 3)
@@ -62,9 +58,10 @@
   )

-"Pour rappel, Clojure est constitué de formes. Formes ont une structure uniforme. Ils se composent de littéraux et les opérations. Opérations consistent en des formulaires joints entre parenthèses.
-
-Pour faire bonne mesure, voici quelque chose qui ne est pas une forme parce qu'il n'a pas une parenthèse de fermeture:"
+"Pour récapituler, Clojure est constitué de **form**. Les **forms** ont une structure uniforme. Ils se composent de littéraux et les opérations.
+Les opérations sont des forms entourés entre parenthèses.
+
+Pour faire bonne mesure, voici quelque chose qui n'est pas une form parce qu'il n'a pas une parenthèse fermante:"

 [[{:lang "Clojure"}]]
@@ -72,7 +69,9 @@
 (+
 "]]

-"Uniformité structurelle de Clojure est probablement différente de ce que vous êtes habitué. Dans d'autres langues, différentes opérations peuvent avoir différentes structures en fonction de l'opérateur et les opérandes. Par exemple, JavaScript emploie un assortiment de notation infixe, les opérateurs points, et les parenthèses:"
+"L'uniformité structurelle de Clojure est probablement différente de ce que vous êtes habitué.
+Dans d'autres langues, différentes opérations peuvent avoir différentes structures en fonction de l'opérateur et les opérandes.
+Par exemple, JavaScript emploie un assortiment de notation infixe, les opérateurs points, et les parenthèses:"

 (comment

@@ -80,14 +79,15 @@
   "It was the panda " .concat ("in the library ", "with a dust buster")
   )

-"La structure de Clojure est très simple et cohérent par comparaison. Peu importe ce que l'opérateur vous utilisez ou quel type de données que vous êtes d'exploitation sur, la structure est la même.
-
-Une dernière remarque: je utilise aussi l'expression de terme pour désigner les formes Clojure. Ne soyez pas trop accroché sur la terminologie, cependant."
+"La structure de Clojure est très simple et cohérent par comparaison.
+ Peu importe l'opérateur vous utilisez ou quel type de données que vous êtes d'exploitation sur, la structure est la même.
+
+Une dernière remarque: j'utilise aussi l'expression de terme pour désigner les forms Clojure. Ne soyez pas trop accroché sur la terminologie, cependant."

 [[:section {:tag "flow_control" :title "Flow Control"}]]

-"Voici quelques opérateurs de contrôle de flux de base. Tout au long du livre, vous rencontrez plus."
+"Voici quelques opérateurs de contrôle de flux de base. Tout au long tuto, vous rencontrez plus."

 [[:subsection {:tag "if" :title "if"}]]
@@ -173,7 +173,7 @@

 [[:subsection {:tag "do" :title "do"}]]

-"*do* vous permet de «boucler» des formes multiples. Essayez ce qui suit dans votre REPL:"
+"*do* vous permet de «boucler» des forms multiples. Essayez ce qui suit dans votre REPL:"

 (comment
   (if true
@@ -998,10 +998,10 @@
   220 ; final evaluation
   )

-[[:section {:tags "appel_de_fonctions_macro_forme_special" :title "Fonction, macro, et formes spéciales"}]]
-
-
-"Dans la dernière section, vous avez appris que les appels de fonction sont des expressions qui ont une expression de fonction en tant qu'opérateur. Il existe deux autres types d'expressions: appels de macro et **formes spéciales**. Vous avez déjà vu un couple formes spéciales:"
+[[:section {:tags "appel_de_fonctions_macro_forme_special" :title "Fonction, macro, et forms spéciales"}]]
+
+
+"Dans la dernière section, vous avez appris que les appels de fonction sont des expressions qui ont une expression de fonction en tant qu'opérateur. Il existe deux autres types d'expressions: appels de macro et **forms spéciales**. Vous avez déjà vu un couple forms spéciales:"

 (comment

@@ -1011,7 +1011,7 @@
     (def error-message (str error-message "DOOOOOOOMED!")))
   )

-"Vous apprendrez tout ce qu'il ya à savoir sur les appels de macro et les formes spéciales dans le chapitre \"Clojure Alchemy: lecture, l'évaluation et les macros». Pour l'instant, cependant, la principale caractéristique qui rend formes spéciales \"spécial\", ce est qu'ils ne évaluent pas toujours tous leurs opérandes, contrairement appels de fonction.
+"Vous apprendrez tout ce qu'il ya à savoir sur les appels de macro et les forms spéciales dans le chapitre \"Clojure Alchemy: lecture, l'évaluation et les macros». Pour l'instant, cependant, la principale caractéristique qui rend forms spéciales \"spécial\", ce est qu'ils ne évaluent pas toujours tous leurs opérandes, contrairement appels de fonction.
 Prenez if , par exemple. Sa structure générale est:"

 (comment
@@ -1032,11 +1032,11 @@

 "Si Clojure évalué deux tweet appels de fonction, puis tes followers finiraient très confus.

-Une autre caractéristique qui différencie les formes spéciales, ce est que vous ne pouvez pas les utiliser comme arguments de fonctions.
-
-En général, les formes particulières à mettre en œuvre la fonctionnalité Clojure de base qui ne peut pas être mis en œuvre avec des fonctions. Il ya seulement une poignée de formes spéciales Clojure, et il est assez étonnant que cette langue riche est mis en œuvre avec un tel petit ensemble de blocs de construction.
-
-Macros sont semblables à des formes particulières en ce qu'elles évaluent leurs opérandes différemment des appels de fonction et ils ont aussi ne peuvent pas être passés comme arguments à des fonctions. Mais ce détour a pris assez longtemps; il est temps d'apprendre à définir des fonctions!"
+Une autre caractéristique qui différencie les forms spéciales, ce est que vous ne pouvez pas les utiliser comme arguments de fonctions.
+
+En général, les forms particulières à mettre en œuvre la fonctionnalité Clojure de base qui ne peut pas être mis en œuvre avec des fonctions. Il ya seulement une poignée de forms spéciales Clojure, et il est assez étonnant que cette langue riche est mis en œuvre avec un tel petit ensemble de blocs de construction.
+
+Macros sont semblables à des forms particulières en ce qu'elles évaluent leurs opérandes différemment des appels de fonction et ils ont aussi ne peuvent pas être passés comme arguments à des fonctions. Mais ce détour a pris assez longtemps; il est temps d'apprendre à définir des fonctions!"

 [[:section {:tags "definition_de_fonctions" :title "Définition de fonctions"}]]
@@ -1361,7 +1361,7 @@

   [[:subsection {:tags "corps_de_fonction" :title "Corps de fonction"}]]

-"Votre corps de la fonction peut contenir des formes. Clojure retourne automatiquement la dernière forme évalué:"
+"Votre corps de la fonction peut contenir des forms. Clojure retourne automatiquement la dernière forme évalué:"

 (comment
   (defn illustrative-function
@@ -1817,9 +1817,9 @@

 "Notez que la valeur d'un *let* forme est la dernière forme dans son corps qui obtient évaluée.

-*let* formes suivent les règles de déstructuration qui nous introduit dans «Appel d'une fonction\" ci-dessus.
-
-Une façon de penser *let* formes, ce est qu'ils fournissent des paramètres et leurs arguments secondaires à côte. *let* formes ont deux utilisations principales:
+*let* forms suivent les règles de déstructuration qui nous introduit dans «Appel d'une fonction\" ci-dessus.
+
+Une façon de penser *let* forms, ce est qu'ils fournissent des paramètres et leurs arguments secondaires à côte. *let* forms ont deux utilisations principales:

 * Ils fournissent la clarté en vous permettant de nommer les choses
 * Ils vous permettent d'évaluer une expression qu'une seule fois et ré-utiliser le résultat. Ceci est particulièrement important lorsque vous avez besoin de réutiliser le résultat d'un appel de fonction coûteux, comme un appel d'API de réseau. Il est également important lorsque l'expression a des effets secondaires.