Add more tests for the context data forwarding.

--- test/catacumba/core_tests.clj
+++ test/catacumba/core_tests.clj
@@ -277,6 +277,29 @@
         (is (= (:body response) "hello world cps"))
         (is (= (:status response) 200))))))

+(deftest context-data-forwarding
+  (letfn [(handler1 [context]
+            (ct/delegate context {:foo 1}))
+          (handler2 [context]
+            (ct/delegate context {:bar 2}))
+          (handler3 [context]
+            (ct/delegate context {:baz (+ (:foo context)
+                                          (:bar context))}))
+          (handler4 [p context]
+            (deliver p (select-keys context [:foo :bar :baz]))
+            "hello world")]
+    (let [p (promise)]
+      (with-server {:handler (ct/routes [[:any handler1]
+                                              [:any handler2]
+                                              [:any handler3]
+                                              [:any (partial handler4 p)]])}
+      (let [response (client/get base-url)]
+        (is (= (:body response) "hello world"))
+        (is (= (:status response) 200))
+        (is (= (deref p 1000 nil)
+               {:foo 1 :bar 2 :baz 3})))))))
+
+
 ;; (deftest experiments
 ;;   (letfn [(handler1 [context]
 ;;             (println 1111)


Adapt tests.

Adapt tests.

--- test/cats/labs/lens_spec.cljc
+++ test/cats/labs/lens_spec.cljc
@@ -5,7 +5,8 @@
                [clojure.test.check.generators :as gen :include-macros true]
                [clojure.test.check.properties :as prop :include-macros true]
                [cats.core :as m]
-               [cats.labs.lens :as l])
+               [cats.labs.lens :as l]
+               [cats.labs.traversals :as tv])
      :clj
      (:require [clojure.test :as t]
                [clojure.test.check]
@@ -13,7 +14,8 @@
                [clojure.test.check.generators :as gen]
                [clojure.test.check.properties :as prop]
                [cats.core :as m]
-               [cats.labs.lens :as l]))
+               [cats.labs.lens :as l]
+               [cats.labs.traversals :as tv]))
   #?(:cljs
      (:require-macros [clojure.test.check.clojure-test :refer (defspec)])))

@@ -221,13 +223,13 @@

 (defn first-traversal-law [{:keys [gen trav]}]
   (prop/for-all [s gen]
-    (coll? (l/foci trav s))))
+    (coll? (tv/foci trav s))))

 ;; it

 (def it-traversal
   {:gen gen/any
-   :trav l/it})
+   :trav tv/it})

 (defspec it-first-traversal-law 10
   (first-traversal-law it-traversal))
@@ -236,7 +238,7 @@

 (def each-traversal
   {:gen gen/any
-   :trav l/each})
+   :trav tv/each})

 (defspec each-first-traversal-law 10
   (first-traversal-law each-traversal))
@@ -245,7 +247,7 @@

 (def filter-traversal
   {:gen gen/any
-   :trav (l/filter identity)})
+   :trav (tv/filter identity)})

 (defspec filter-first-traversal-law 10
   (first-traversal-law filter-traversal))
@@ -254,7 +256,7 @@

 (def only-traversal
   {:gen gen/any
-   :trav (l/only identity)})
+   :trav (tv/only identity)})

 (defspec only-first-traversal-law 10
   (first-traversal-law only-traversal))
@@ -263,7 +265,7 @@

 (def keys-traversal
   {:gen (gen/map gen/keyword gen/any)
-   :trav l/keys})
+   :trav tv/keys})

 (defspec keys-first-traversal-law 10
   (first-traversal-law keys-traversal))
@@ -272,7 +274,7 @@

 (def vals-traversal
   {:gen (gen/map gen/keyword gen/any)
-   :trav l/vals})
+   :trav tv/vals})

 (defspec vals-first-traversal-law 10
   (first-traversal-law vals-traversal))
@@ -281,7 +283,7 @@

 (def indexed-traversal
   {:gen (gen/vector gen/any)
-   :trav l/indexed})
+   :trav tv/indexed})

 (defspec indexed-first-traversal-law 10
   (first-traversal-law indexed-traversal))
@@ -290,7 +292,7 @@

 (def nothing-traversal
   {:gen gen/any
-   :trav l/nothing})
+   :trav tv/nothing})

 (defspec nothing-first-traversal-law 10
   (first-traversal-law nothing-traversal))
@@ -299,7 +301,7 @@

 (def both-traversal
   {:gen (gen/vector gen/int)
-   :trav (l/both (filter odd?) (filter #(< % 5)))})
+   :trav (tv/both (filter odd?) (filter #(< % 5)))})

 (defspec both-first-traversal-law 10
   (first-traversal-law both-traversal))
@@ -308,7 +310,7 @@

 (def lens->traversal
   {:gen (with-key :a)
-   :trav (l/lens->traversal (l/key :a))})
+   :trav (tv/lens->traversal (l/key :a))})

 (defspec lens->traversal-first-traversal-law 10
   (first-traversal-law lens->traversal))
@@ -350,7 +352,7 @@
 (t/deftest foci-atom
   (t/testing "Reflects an atoms focused values"
     (let [source (atom [0 1 2 3 4 5])
-          fsource (l/foci-atom (l/only odd?) source)]
+          fsource (tv/foci-atom (tv/only odd?) source)]
       (t/is (= @fsource [1 3 5]))

       (swap! source #(subvec % 2))
@@ -365,7 +367,7 @@
   (t/testing "Supports watches"
     (let [source (atom [1 2 3 4 5])
           watched (volatile! nil)
-          fsource (l/foci-atom (l/only odd?) source)]
+          fsource (tv/foci-atom (tv/only odd?) source)]
       (add-watch fsource :test (fn [key ref old new]
                                  (vreset! watched [ref old new])))


Temporarily commented out broken tests, since ring-mock does not work

--- test/cfpb/qu/handler_test.clj
+++ test/cfpb/qu/handler_test.clj
@@ -43,7 +43,7 @@
              => (contains {:status 404})))

-(facts "about /data/:dataset/slice/:slice"
+#_(facts "about /data/:dataset/slice/:slice"
        (fact "it returns successfully when the dataset and slice exist"
              (prerequisite (#'cfpb.qu.data/get-metadata "good-dataset") => {:slices {:whoa {}}}
                            (#'cfpb.qu.query/execute "good-dataset" anything anything)


Add test for drop counter.

Add test for drop counter.

--- test/dsbdp/test/local_data_processing_pipeline_tests.clj
+++ test/dsbdp/test/local_data_processing_pipeline_tests.clj
@@ -127,6 +127,19 @@
     (interrupt proc-element-1)
     (interrupt proc-element-2)))

+(deftest simple-local-processing-element-counter-drop-test
+  (let [in-queue (LinkedTransferQueue.)
+        proc-element (create-local-processing-element in-queue
+                                                      (fn [_ _]))]
+    (.put in-queue (LocalTransferContainer. "in" "out"))
+    (.put in-queue (LocalTransferContainer. "in" "out"))
+    (.put in-queue (LocalTransferContainer. "in" "out"))
+    (sleep 100)
+    (let [cntr (get-counts proc-element)]
+      (is (= 0 (:out cntr)))
+      (is (= 3 (:dropped cntr))))
+    (interrupt proc-element)))
+

 (deftest simple-local-pipeline-send-test


Two simple tests for with-out-str

Two simple tests for with-out-str

--- test/cljs/cljs/core_test.cljs
+++ test/cljs/cljs/core_test.cljs
@@ -246,6 +246,8 @@

   (assert (= "" (pr-str)))
   (assert (= "\n" (prn-str)))
+  (assert  (= "12" (with-out-str (print 1) (print 2))))
+  (assert  (= "12" (with-out-str (*print-fn* 1) (*print-fn* 2))))

   ;;this fails in v8 - why?
   ;(assert (= "symbol\"'string" (pr-str (str 'symbol \" \' "string"))))


turn off optimiser println

turn off optimiser println

--- test/cortex/optimise_test.clj
+++ test/cortex/optimise_test.clj
@@ -17,7 +17,7 @@
             m (backward m (m/mul (m/sub (output m) target) 2.0))
             [o m] (optimise o m)
             dist (m/length (m/sub (output m) target))]
-        (println (output m))
+        ;; (println (output m))
         (if (< i 100)
           (recur (inc i) m o)
           (is (< dist 0.001)))))))


Use metadata instead of ns to determine free vars

--- test/desdemona/query_test.clj
+++ test/desdemona/query_test.clj
@@ -154,15 +154,6 @@
     #{'x}
     '(clojure.core.logic/featurec x {:ip "10.0.0.1"})))

-(deftest free-sym-tests
-  (is (#'q/free-sym 'x))
-  (is (#'q/free-sym 'y))
-
-  (is (not (#'q/free-sym 'clojure.core/=))
-      "fully qualified")
-  (is (not (#'q/free-sym 1))
-      "not a symbol"))
-
     ;; #{'x}
     ;; '(clojure.core.logic/conde
     ;;   [(clojure.core.logic/featurec x {:ip "10.0.0.1"})


if-let* tests

if-let* tests

--- test/atom_finder/util_test.clj
+++ test/atom_finder/util_test.clj
@@ -101,6 +101,18 @@
                       {"good1" 1, "bad1" 1, "good2" 2, "bad2" 2})
            {"good1" 1, "good2" 2}))
     )
+
+  (testing "if-let*"
+    (is (= 2 (if-let* [a 1] 2 3)))
+    (is (= 3 (if-let* [a nil] 2 3)))
+    (is (= 2 (if-let* [a 1 b 4] 2 3)))
+    (is (= 3 (if-let* [a nil b 4] 2 3)))
+    (is (= 3 (if-let* [a 1 b nil] 2 3)))
+    (is (= 3 (if-let* [a nil b nil] 2 3)))
+    (is (= 3 (if-let* [a false b true] 2 3)))
+    (is (= 2 (if-let* [a true b true c true] 2 3)))
+    (is (= 3 (if-let* [a true b true c nil] 2 3)))
+    )
   )

 (deftest writer-util-test


[#3073] Base max group order in max fun instead of count

--- backend/src/akvo/lumen/lib/transformation/engine.clj
+++ backend/src/akvo/lumen/lib/transformation/engine.clj
@@ -198,9 +198,9 @@
               ]
           (db.dataset-version/new-dataset-version-2 tenant-conn next-dataset-version)
           (when data-groups-to-be-created
-            (let [max-group-order (count data-groups)
+            (let [max-group-order (apply max (conj (map :group-order data-groups) 1000))
                   adapted-data-groups (map-indexed (fn [i item]
-                                                     (let [idx (inc (+ 1000 i max-group-order))
+                                                     (let [idx (inc (+ i max-group-order))
                                                            group-name (str (:group-name item) " [merge]")]
                                                        (-> item
                                                            (assoc :group-order idx)


Ensure fetched frames have correct structure

--- test/asciinema_player/core_test.cljs
+++ test/asciinema_player/core_test.cljs
@@ -45,3 +45,7 @@
     (is (= (c/next-frames frames 11) [[1 :c]]))
     (is (= (c/next-frames frames 12) []))
     (is (= (c/next-frames frames 13) []))))
+
+(deftest frames-json->clj-test
+  (let [frames [[1.2 {"lines" {"0" [["foo" {"fg" 1}]] "1" [["bar" {"bg" 2}]]} "cursor" {"x" 1 "y" 2 "visible" false}}]]]
+    (is (= (c/frames-json->clj frames) [[1.2 {:lines {0 [["foo" {:fg 1}]] 1 [["bar" {:bg 2}]]} :cursor {:x 1 :y 2 :visible false}}]]))))


New tests: test-get-preview-test-job-suffix1/2

--- test/emender_jenkins/config_test.clj
+++ test/emender_jenkins/config_test.clj
@@ -392,6 +392,23 @@
             (get-test-jobs-prefix {:configuration nil}) nil
             (get-test-jobs-prefix nil) nil)))

+(deftest test-get-preview-test-jobs-suffix-1
+    "Check the behaviour of function emender-jenkins.config/get-preview-test-jobs-suffix."
+    (testing "the behaviour of function emender-jenkins.config/get-preview-test-jobs-suffix."
+        (are [x y] (= x y)
+            (get-preview-test-jobs-suffix {:configuration {:jobs {:preview-test-jobs-suffix nil}}})   nil
+            (get-preview-test-jobs-suffix {:configuration {:jobs {:preview-test-jobs-suffix false}}}) false
+            (get-preview-test-jobs-suffix {:configuration {:jobs {:preview-test-jobs-suffix true}}})  true
+            (get-preview-test-jobs-suffix {:configuration {:jobs {:preview-test-jobs-suffix "xyzzy"}}}) "xyzzy")))
+
+(deftest test-get-preview-test-jobs-suffix-2
+    "Check the behaviour of function emender-jenkins.config/get-preview-test-jobs-suffix."
+    (testing "the behaviour of function emender-jenkins.config/get-preview-test-jobs-suffix."
+        (are [x y] (= x y)
+            (get-preview-test-jobs-suffix {:configuration {:jobs nil}}) nil
+            (get-preview-test-jobs-suffix {:configuration nil}) nil
+            (get-preview-test-jobs-suffix nil) nil)))
+
 (deftest test-override-options-by-cli-1
     "Check the behaviour of function emender-jenkins.config/override-options-by-cli."
     (testing "the behaviour of function emender-jenkins.config/override-options-by-cli."


added a basic test

added a basic test

--- test/jasons_game/core_test.clj
+++ test/jasons_game/core_test.clj
@@ -2,6 +2,11 @@
   (:use clojure.test
         jasons_game.core))

-(deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))
+(deftest test-parse-sentence-text
+  (testing "Parse sentence text"
+           (is (=
+                 '{:phrases
+                   ({:words ({:target :speaker, :text "I"})}
+                     {:words ({:text "love"})}
+                     {:words ({:target :addressee, :text "you"})})}
+                 (parse-sentence-text "I love you")))))


fixing another server test error

fixing another server test error

--- test/kioo/server/core_test.clj
+++ test/kioo/server/core_test.clj
@@ -93,7 +93,7 @@
   (testing "set-style test"
     (let [comp (component "style-span.html" [:span]
                           {[:#s] (set-style :display "none")})]
-      (is (= "testing"
+      (is (= "testing"
              comp))))
   (testing "remove-style test"
     (let [comp (component "style-span.html" [:span]


Refactor

Refactor

--- backend/src/akvo/lumen/lib/transformation/derive.clj
+++ backend/src/akvo/lumen/lib/transformation/derive.clj
@@ -23,6 +23,21 @@
           double-quote-template
           (throw (ex-info (str "Problem with js row template with code: " s) {:s s}))))
       single-quote-template)))
+
+(defn columnName>columnTitle
+  "Replace code column references and fall back to use code pattern if there is no
+  references."
+  [computed columns]
+  (let [columns (walk/keywordize-keys columns)]
+    (reduce (fn [code {:strs [column-name id pattern]}]
+              (if column-name
+                (str/replace code id (format (row-template-format pattern)
+                                             (-> (try (dataset.utils/find-column columns column-name)
+                                                      (catch Exception e nil))
+                                                 :title)))
+                (str/replace code id pattern)))
+            (get computed "template")
+            (get computed "references"))))

 (defn parse-row-object-references
   "Parse js code and return a sequence of row-references e.g. row.foo row['foo']
@@ -53,21 +68,6 @@
             {"template" code
              "references" []}
             (parse-row-object-references code))))
-
-(defn columnName>columnTitle
-  "Replace code column references and fall back to use code pattern if there is no
-  references."
-  [computed columns]
-  (let [columns (walk/keywordize-keys columns)]
-    (reduce (fn [code {:strs [column-name id pattern]}]
-              (if column-name
-                (str/replace code id (format (row-template-format pattern)
-                                             (-> (try (dataset.utils/find-column columns column-name)
-                                                      (catch Exception e nil))
-                                                 :title)))
-                (str/replace code id pattern)))
-            (get computed "template")
-            (get computed "references"))))

 (defmethod engine/adapt-transformation "core/derive"
   [op-spec older-columns new-columns]


fixing externs.clj problem

fixing externs.clj problem

--- env/dev/externs.clj
+++ env/dev/externs.clj
@@ -87,7 +87,12 @@
   "Return the ClojureScript AST for the contents of filename. Tends to
   be large and to contain cycles -- be careful printing at the REPL."
   [filename]
-  (binding [ana/*cljs-ns* 'cljs.user ;; default namespace
+  (binding [ana/*unchecked-if* false
+            #_*err* #_(if bind-err
+                    (cond-> *out*
+                            (not (instance? PrintWriter *out*)) (PrintWriter.))
+                    *err*)
+            ana/*cljs-ns* 'cljs.user ;; default namespace
             ana/*cljs-file* filename]
     (mapv
      (fn [form]


NumericRange queries can be configured to use index or fielddata execution mode and can be configured to save to the filter cache

--- search-app/src/cmr/search/data/query_to_elastic.clj
+++ search-app/src/cmr/search/data/query_to_elastic.clj
@@ -6,7 +6,11 @@
             [cmr.search.data.datetime-helper :as h]
             [cmr.common.services.errors :as errors]
             [cmr.search.data.messages :as m]
-            [cmr.search.data.keywords-to-elastic :as k2e]))
+            [cmr.search.data.keywords-to-elastic :as k2e]
+            [cmr.common.config :as cfg]))
+
+(def numeric-range-execution-mode (cfg/config-value-fn :numeric-range-execution-mode "index"))
+(def numeric-range-use-cache (cfg/config-value-fn "true" :numeric-range-use-cache #(= "true" %)))

 (def field-mappings
   "A map of fields in the query to the field name in elastic. Field names are excluded from this
@@ -106,22 +110,27 @@
 (defn- range-condition->elastic
   "Convert a range condition to an elastic search condition. Execution
   should either by 'fielddata' or 'index'."
-  [field min-value max-value execution]
-  (cond
-    (and min-value max-value)
-    {:range {field {:gte min-value :lte max-value}
-             :execution execution}}
-
-    min-value
-    {:range {field {:gte min-value}
-             :execution execution}}
-
-    max-value
-    {:range {field {:lte max-value}
-             :execution execution}}
-
-    :else
-    (errors/internal-error! (m/nil-min-max-msg))))
+  ([field min-value max-value execution]
+   (range-condition->elastic field min-value max-value execution true))
+  ([field min-value max-value execution use-cache]
+   (cond
+     (and min-value max-value)
+     {:range {field {:gte min-value :lte max-value}
+              :execution execution
+              :_cache use-cache}}
+
+     min-value
+     {:range {field {:gte min-value}
+              :execution execution
+              :_cache use-cache}}
+
+     max-value
+     {:range {field {:lte max-value}
+              :execution execution
+              :_cache use-cache}}
+
+     :else
+     (errors/internal-error! (m/nil-min-max-msg)))))

 (extend-protocol ConditionToElastic
   cmr.search.models.query.ConditionGroup
@@ -204,7 +213,8 @@
   (condition->elastic
     [{:keys [field min-value max-value]} concept-type]
     (range-condition->elastic (query-field->elastic-field field concept-type)
-                              min-value max-value "index"))
+                              min-value max-value (numeric-range-execution-mode) (numeric-range-use-cache)))
+

   cmr.search.models.query.NumericRangeIntersectionCondition
   (condition->elastic
@@ -212,19 +222,23 @@
     {:or [(range-condition->elastic (query-field->elastic-field min-field concept-type)
                                     min-value
                                     max-value
-                                    "index")
+                                    (numeric-range-execution-mode)
+                                    (numeric-range-use-cache))
           (range-condition->elastic (query-field->elastic-field max-field concept-type)
                                     min-value
                                     max-value
-                                    "index")
+                                    (numeric-range-execution-mode)
+                                    (numeric-range-use-cache))
           {:and [(range-condition->elastic (query-field->elastic-field min-field concept-type)
                                            nil
                                            min-value
-                                           "index")
+                                           (numeric-range-execution-mode)
+                                           (numeric-range-use-cache))
                  (range-condition->elastic (query-field->elastic-field max-field concept-type)
                                            max-value
                                            nil
-                                           "index")]}]})
+                                           (numeric-range-execution-mode)
+                                           (numeric-range-use-cache))]}]})

   cmr.search.models.query.StringRangeCondition
   (condition->elastic


Add caddisfly uuid to caddisfly question response [#137]

--- api/src/clojure/org/akvo/flow_api/datastore/survey.clj
+++ api/src/clojure/org/akvo/flow_api/datastore/survey.clj
@@ -22,13 +22,17 @@
          (filter #(= (:folder-id %) folder-id)))))

 (defn ->question [question]
-  {:id (str (ds/id question))
-   :name (.getText question)
-   :type (str (.getType question))
-   :order (.getOrder question)
-   :variable-name (.getVariableName question)
-   :created-at (ds/created-at question)
-   :modified-at (ds/modified-at question)})
+  (let [type* (str (.getType question))]
+    (merge
+     {:id (str (ds/id question))
+      :name (.getText question)
+      :type type*
+      :order (.getOrder question)
+      :variable-name (.getVariableName question)
+      :created-at (ds/created-at question)
+      :modified-at (ds/modified-at question)}
+     (when (= type* "CADDISFLY")
+       {:caddisfly-resource-uuid (.getCaddisflyResourceUuid question)}))))

 (defn question-group-definition [question-group questions]
   (let [qs (sort-by :order (map ->question questions))]


Fix Typo

Fix Typo

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

--- src/conexp/contrib/dl/languages/description_graphs.clj
+++ src/conexp/contrib/dl/languages/description_graphs.clj
@@ -206,7 +206,7 @@

 (defn- concept-graph
   "Returns the concept graph of a tbox-map. The graph has the defined
-  conecpts of tbox as vertices and connects every two vertices C to D
+  concepts of tbox as vertices and connects every two vertices C to D
   if D appears in the top-level conjunction of C."
   [tbox-map]
   (let [defined-concepts (set (keys tbox-map))]


uncommented executor-id->tasks

uncommented executor-id->tasks

--- storm-multicore/src/clj/backtype/storm/daemon/common.clj
+++ storm-multicore/src/clj/backtype/storm/daemon/common.clj
@@ -205,25 +205,7 @@
 ;
 ;
 ;
-;(defn executor-id->tasks [[first-task-id last-task-id]]
-;  (->> (range first-task-id (inc last-task-id))
-;       (map int)))
-;
-;(defn worker-context [worker]
-;  (WorkerTopologyContext. (:system-topology worker)
-;                          (:storm-conf worker)
-;                          (:task->component worker)
-;                          (:component->sorted-tasks worker)
-;                          (:component->stream->fields worker)
-;                          (:storm-id worker)
-;                          (supervisor-storm-resources-path
-;                            (supervisor-stormdist-root (:conf worker) (:storm-id worker)))
-;                          (worker-pids-root (:conf worker) (:worker-id worker))
-;                          (:port worker)
-;                          (:task-ids worker)
-;                          (:default-shared-resources worker)
-;                          (:user-shared-resources worker)
-;                          ))
+;
 ;
 ;
 ;(defn to-task->node+port [executor->node+port]
@@ -259,6 +241,29 @@
         (halt-process! 13 "Error on initialization")
         )))))

+
+;(defn worker-context [worker]
+;  (WorkerTopologyContext. (:system-topology worker)
+;    (:storm-conf worker)
+;    (:task->component worker)
+;    (:component->sorted-tasks worker)
+;    (:component->stream->fields worker)
+;    (:storm-id worker)
+;    (supervisor-storm-resources-path
+;      (supervisor-stormdist-root (:conf worker) (:storm-id worker)))
+;    (worker-pids-root (:conf worker) (:worker-id worker))
+;    (:port worker)
+;    (:task-ids worker)
+;    (:default-shared-resources worker)
+;    (:user-shared-resources worker)
+;    ))
+
+
+(defn executor-id->tasks
+  "[1 ] -> [1 2 3 4]"
+  [[first-task-id last-task-id]]
+  (->> (range first-task-id (inc last-task-id))
+       (map int)))

 (defn num-start-executors
   "Returns the number of executors to start with."


Update catacumba version on single-file example.

--- examples/single-file/main.clj
+++ examples/single-file/main.clj
@@ -1,7 +1,7 @@
 #!/usr/bin/env boot
 (set-env!
- :dependencies '[[org.clojure/clojure "1.7.0-RC1" :scope "provided"]
-                 [funcool/catacumba "0.2.0-SNAPSHOT"]])
+ :dependencies '[[org.clojure/clojure "1.7.0-RC1"]
+                 [funcool/catacumba "0.2.0"]])

 (require '[catacumba.core :as ct])


Removing dead tribes

Removing dead tribes

--- src/civs/logic.clj
+++ src/civs/logic.clj
@@ -18,8 +18,15 @@
          game (reduce (fn [acc, _] (:game (generate-tribe acc))) game (repeat n-tribes :just_something))]
     game))

+(defn- clean-game
+  "Remove dead tribes"
+  [game]
+  (let [tribes-map         (.tribes game)
+        updated-tribes-map (select-keys tribes-map (for [[id tribe] tribes-map :when (alive? tribe)] id))]
+    (assoc game :tribes updated-tribes-map)))
+
 (defn turn [game]
   (let [ tribes (vals (.tribes game))]
-    (reduce (fn [acc t] (tribe-turn acc t)) game tribes)))
+    (clean-game (reduce (fn [acc t] (tribe-turn acc t)) game tribes))))

 ;(repeatedly 100 (fn [] (def g (turn g))))


Wire up new SNES controller.

Wire up new SNES controller.

--- src/clojure/playasophy/wonderdome/input/gamepad.clj
+++ src/clojure/playasophy/wonderdome/input/gamepad.clj
@@ -86,19 +86,19 @@

-;;;;; SNES CONTROLLER ;;;;;
-
-(def ^:const snes-vendor-id  0x12bd)
-(def ^:const snes-product-id 0xd015)
-
-(def ^:private snes-axes
+;;;;; ORIGINAL SNES CONTROLLER ;;;;;
+
+(def ^:const og-snes-vendor-id  0x12bd)
+(def ^:const og-snes-product-id 0xd015)
+
+(def ^:private og-snes-axes
   {:x-axis 0.0
    :y-axis 0.0})

-(def ^:private snes-buttons
+(def ^:private og-snes-buttons
   #{:X :A :B :Y :L :R :select :start :left :right :up :down})

-(def ^:private snes-bits
+(def ^:private og-snes-bits
   {:X      [3 0]
    :A      [3 1]
    :B      [3 2]
@@ -109,7 +109,7 @@
    :start  [4 1]})

-(defn- snes-read-state
+(defn- og-snes-read-state
   "SNES controller state is read 8 bytes at a time:
     byte 0: x-axis [00 7F FF] (FF is right)
     byte 1: y-axis [00 7F FF] (FF is down)
@@ -125,6 +125,81 @@
     (let [x-axis (byte-axis (aget buffer 0))
           y-axis (- (byte-axis (aget buffer 1)))]
       (assoc
+        (read-buttons og-snes-bits buffer)
+        :x-axis x-axis
+        :y-axis y-axis
+        :left  (neg? x-axis)
+        :right (pos? x-axis)
+        :down  (neg? y-axis)
+        :up    (pos? y-axis)))))
+
+
+(defn- og-snes-state-events
+  [old-state new-state elapsed]
+  (remove nil?
+    (concat
+      (axis-direction-events og-snes-axes old-state elapsed)
+      (button-hold-events og-snes-buttons old-state elapsed)
+      (button-state-events og-snes-buttons old-state new-state))))
+
+
+(defn og-snes
+  "Creates a new SNES gamepad input which will send button events to the given
+  channel."
+  [channel]
+  {:pre [(some? channel)]}
+  ; TODO: sometimes nil when refreshing code...
+  (if-let [device (usb/find-device og-snes-vendor-id og-snes-product-id)]
+    (usb/hid-input
+      :snes
+      channel
+      device
+      og-snes-read-state
+      og-snes-state-events)))
+
+
+
+;;;;; NEW SNES CONTROLLER ;;;;;
+
+(def ^:const snes-vendor-id  2064)
+(def ^:const snes-product-id 58625)
+
+(def ^:private snes-axes
+  {:x-axis 0.0
+   :y-axis 0.0})
+
+(def ^:private snes-buttons
+  #{:X :A :B :Y :L :R :select :start :left :right :up :down})
+
+(def ^:private snes-bits
+  {:X      [5 4]
+   :A      [5 5]
+   :B      [5 6]
+   :Y      [5 7]
+   :L      [6 0]
+   :R      [6 1]
+   :select [6 4]
+   :start  [6 5]})
+
+
+(defn- snes-read-state
+  "SNES controller state is read 8 bytes at a time:
+    byte 0: always 01
+    byte 1: always 80
+    byte 2: always 80
+    byte 3: x-axis [00 7F FF] (FF is right)
+    byte 4: y-axis [00 7F FF] (FF is down)
+    byte 5: 0F + X (10), A (20), B (40), Y (80)
+    byte 6: L (1), R (2), select (10), start (20)
+    byte 7: always 00"
+  [^bytes buffer len]
+  (if (< len 8)
+    (log/warn
+      (str "Incomplete data read from SNES controller: "
+           (apply str (map (partial format "%02X") (take len buffer)))))
+    (let [x-axis (byte-axis (aget buffer 3))
+          y-axis (- (byte-axis (aget buffer 4)))]
+      (assoc
         (read-buttons snes-bits buffer)
         :x-axis x-axis
         :y-axis y-axis


fixed var ref in schema

fixed var ref in schema

--- sidecar/src/figwheel_sidecar/schemas/cljs_options.clj
+++ sidecar/src/figwheel_sidecar/schemas/cljs_options.clj
@@ -734,54 +734,54 @@
    map?

    (attach-warning ":asset-path has no effect without a :main"
-                   (fn [{:keys [main] :as comp}]
-                     (not (and (contains? comp :asset-path)
+                   (fn [{:keys [main] :as cmpl}]
+                     (not (and (contains? cmpl :asset-path)
                                (nil? main)))))

    (attach-warning ":pseudo-names has no effect when :optimizations is not :advanced"
-                   (fn [{:keys [optimizations] :as comp}]
-                     (not (and (contains? comp :pseudo-names)
+                   (fn [{:keys [optimizations] :as cmpl}]
+                     (not (and (contains? cmpl :pseudo-names)
                                (not= optimizations :advanced)))))

    ;; **** TODO add in the cljs.compiler unknown/similar-key warning here

    ;; these next warnings probably be elevated to an errors attach-reason
    (attach-warning ":preamble has no effect when :optimizations is not :none"
-                   (fn [{:keys [optimizations] :as comp}]
-                     (not (and (contains? comp :preamble)
+                   (fn [{:keys [optimizations] :as cmpl}]
+                     (not (and (contains? cmpl :preamble)
                                (not (opt-none? optimizations))))))

    (attach-warning ":hashbang has no effect when :target is not :nodejs"
-                   (fn [{:keys [target] :as comp}]
-                     (not (and (contains? comp :hashbang) (not= target :nodejs)))))
+                   (fn [{:keys [target] :as cmpl}]
+                     (not (and (contains? cmpl :hashbang) (not= target :nodejs)))))

    (attach-warning ":clojure-defines has no effect when :optimizations is :whitespace"
-                   (fn [{:keys [optimizations] :as comp}]
-                     (not (and (contains? comp :closure-defines)
+                   (fn [{:keys [optimizations] :as cmpl}]
+                     (not (and (contains? cmpl :closure-defines)
                                (= :whitespace optimizations)))))

    (attach-warning "missing an :output-to option - you probably will want this ..."
-                   (fn [comp] (contains? comp :output-to)))
+                   (fn [cmpl] (contains? cmpl :output-to)))

    (attach-reason  ":closure-defines requires a :main when :optimizations is :none"
-                   (fn [{:keys [optimizations main] :as comp}]
-                     (not (and (contains? comp :closure-defines)
+                   (fn [{:keys [optimizations main] :as cmpl}]
+                     (not (and (contains? cmpl :closure-defines)
                                (nil? main)
                                (opt-none? optimizations))))
                    :focus-key :closure-defines)

    (attach-reason  ":source-map must be a boolean when :optimizations is :none"
-                   (fn [{:keys [source-map optimizations] :as comp}]
+                   (fn [{:keys [source-map optimizations] :as cmpl}]
                      (not (and
-                           (contains? comp :source-map)
+                           (contains? cmpl :source-map)
                            (not (boolean? source-map))
                            (opt-none? optimizations))))
                    :focus-key :source-map)

    (attach-reason  ":source-map must be a string? when :optimizations is not :none"
-                   (fn [{:keys [source-map optimizations] :as cmp}]
+                   (fn [{:keys [source-map optimizations] :as cmpl}]
                      (not (and
-                           (contains? comp :source-map)
+                           (contains? cmpl :source-map)
                            (not (string? source-map))
                            (not (opt-none? optimizations)))))
                    :focus-key :source-map)


decrease default timeout (#275)

decrease default timeout (#275)

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -2033,7 +2033,7 @@
 ;; wait functions
 ;;

-(def ^:dynamic *wait-timeout* 20)
+(def ^:dynamic *wait-timeout* 7)
 (def ^:dynamic *wait-interval* 0.33)


clojure (pgraph-morphisms): changed generic graph function synopses

--- clojure/org/gavrog/clojure/pgraph_morphisms.clj
+++ clojure/org/gavrog/clojure/pgraph_morphisms.clj
@@ -13,8 +13,8 @@

 ;; --- TODO put generic functions into packages under common

-(defn bfs-radius [seed adj]
-  (loop [seen #{seed}, maxdist 0, q (conj empty-queue [seed 0])]
+(defn bfs-radius [adj source]
+  (loop [seen #{source}, maxdist 0, q (conj empty-queue [source 0])]
     (if (empty? q)
       maxdist
       (let [[v d] (first q)
@@ -23,16 +23,16 @@
                (max maxdist d)
                (into (pop q) (map vector ws (repeat (inc d)))))))))

-(defn diameter [all-nodes adj]
-  (apply max (map #(bfs-radius % adj) all-nodes)))
+(defn diameter [adj sources]
+  (apply max (map (partial bfs-radius adj) sources)))

-(defn shells [seed adj]
+(defn bfs-shells [adj source]
   (let [next
         (fn [[prev this]]
           [this (set (for [u this, v (adj u) :when (not (prev v))] v))])]
     (conj
-      (map second (iterate next [#{seed} (set (adj seed))]))
-      #{seed})))
+      (map second (iterate next [#{source} (set (adj source))]))
+      #{source})))

 (defn morphism [v w edge-target incidence-pairs]
   (loop [src2img {}
@@ -94,12 +94,12 @@
   (let [shift (.minus (pos node) (.modZ (pos node)))
         pos* (fn [v] (.minus (cover-node-position pos v) shift))]
     (map (comp sort (partial map pos*))
-         (shells (cover-node net node) adjacent))))
+         (bfs-shells adjacent (cover-node net node)))))

 (defn node-classification [net]
   (let [pos (barycentric-positions net)
         vs (nodes net)
-        dia (diameter vs adjacent)
+        dia (diameter adjacent vs)
         shells (for [v vs]
                  (map vec (take (inc dia) (shell-positions net pos v))))]
     (classify (zipmap vs shells))))


avoids cid bindings in parkable core.async code blocks in get-available-instance (#442)

--- waiter/src/waiter/service.clj
+++ waiter/src/waiter/service.clj
@@ -227,62 +227,60 @@
   "Starts a `clojure.core.async/go` block to query the router state to get an
    available instance to send a request. It will continue to query the state until
    an instance is available."
-  [instance-rpc-chan service-id reason-map app-not-found-fn queue-timeout-ms metric-group]
-  (async/go
-    (cid/with-correlation-id
-      (:cid reason-map)
-      (try
-        (counters/inc! (metrics/service-counter service-id "request-counts" "waiting-for-available-instance"))
-        (statsd/gauge-delta! metric-group "request_waiting_for_instance" +1)
-        (let [expiry-time (t/plus (t/now) (t/millis queue-timeout-ms))]
-          (loop [iterations 1]
-            (let [instance (get-rand-inst instance-rpc-chan service-id reason-map #{} queue-timeout-ms)]
-              (if-not (nil? (:id instance)) ; instance is nil or :no-matching-instance-found
-                (do
-                  (histograms/update!
-                    (metrics/service-histogram service-id "iterations-to-find-available-instance")
-                    iterations)
-                  instance)
-                (if (and instance (not= instance :no-matching-instance-found))
-                  ; instance is a deployment error if it (1) does not have an :id tag, (2) is not nil, and (3) does not equal :no-matching-instance-found
-                  (ex-info (str "Deployment error: " (utils/message instance)) {:service-id service-id :status 503})
-                  (if-not (t/before? (t/now) expiry-time)
-                    (do
-                      ;; No instances were started in a reasonable amount of time
-                      (meters/mark! (metrics/service-meter service-id "no-available-instance-timeout"))
-                      (statsd/inc! metric-group "no_instance_timeout")
-                      (let [outstanding-requests (counters/value (metrics/service-counter service-id "request-counts" "outstanding"))
-                            requests-waiting-to-stream (counters/value (metrics/service-counter service-id "request-counts" "waiting-to-stream"))
-                            waiting-for-available-instance (counters/value (metrics/service-counter service-id "request-counts" "waiting-for-available-instance"))
-                            healthy-instances (counters/value (metrics/service-counter service-id "instance-counts" "healthy"))
-                            unhealthy-instances (counters/value (metrics/service-counter service-id "instance-counts" "unhealthy"))
-                            failed-instances (counters/value (metrics/service-counter service-id "instance-counts" "failed"))]
-                        (ex-info (str "After " (t/in-seconds (t/millis queue-timeout-ms))
-                                      " seconds, no instance available to handle request."
-                                      (when (and (zero? healthy-instances) (or (pos? unhealthy-instances) (pos? failed-instances)))
-                                        " Check that your service is able to start properly!")
-                                      (when (and (pos? outstanding-requests) (pos? healthy-instances))
-                                        " Check that your service is able to scale properly!"))
-                                 {:service-id service-id
-                                  :outstanding-requests outstanding-requests
-                                  :requests-waiting-to-stream requests-waiting-to-stream
-                                  :waiting-for-available-instance waiting-for-available-instance
-                                  :slots-assigned (counters/value (metrics/service-counter service-id "instance-counts" "slots-assigned"))
-                                  :slots-available (counters/value (metrics/service-counter service-id "instance-counts" "slots-available"))
-                                  :slots-in-use (counters/value (metrics/service-counter service-id "instance-counts" "slots-in-use"))
-                                  :work-stealing-offers-received (counters/value (metrics/service-counter service-id "work-stealing" "received-from" "in-flight"))
-                                  :work-stealing-offers-sent (counters/value (metrics/service-counter service-id "work-stealing" "sent-to" "in-flight"))
-                                  :status 503})))
-                    (do
-                      (app-not-found-fn)
-                      (async/<! (async/timeout 1500))
-                      (recur (inc iterations)))))))))
-        (catch Exception e
-          (log/error e "Error in get-available-instance")
-          e)
-        (finally
-          (counters/dec! (metrics/service-counter service-id "request-counts" "waiting-for-available-instance"))
-          (statsd/gauge-delta! metric-group "request_waiting_for_instance" -1))))))
+  [instance-rpc-chan service-id {:keys [cid] :as reason-map} app-not-found-fn queue-timeout-ms metric-group]
+  (async/go
+    (try
+      (counters/inc! (metrics/service-counter service-id "request-counts" "waiting-for-available-instance"))
+      (statsd/gauge-delta! metric-group "request_waiting_for_instance" +1)
+      (let [expiry-time (t/plus (t/now) (t/millis queue-timeout-ms))]
+        (loop [iterations 1]
+          (let [instance (get-rand-inst instance-rpc-chan service-id reason-map #{} queue-timeout-ms)]
+            (if-not (nil? (:id instance)) ; instance is nil or :no-matching-instance-found
+              (do
+                (histograms/update!
+                  (metrics/service-histogram service-id "iterations-to-find-available-instance")
+                  iterations)
+                instance)
+              (if (and instance (not= instance :no-matching-instance-found))
+                ; instance is a deployment error if it (1) does not have an :id tag, (2) is not nil, and (3) does not equal :no-matching-instance-found
+                (ex-info (str "Deployment error: " (utils/message instance)) {:service-id service-id :status 503})
+                (if-not (t/before? (t/now) expiry-time)
+                  (do
+                    ;; No instances were started in a reasonable amount of time
+                    (meters/mark! (metrics/service-meter service-id "no-available-instance-timeout"))
+                    (statsd/inc! metric-group "no_instance_timeout")
+                    (let [outstanding-requests (counters/value (metrics/service-counter service-id "request-counts" "outstanding"))
+                          requests-waiting-to-stream (counters/value (metrics/service-counter service-id "request-counts" "waiting-to-stream"))
+                          waiting-for-available-instance (counters/value (metrics/service-counter service-id "request-counts" "waiting-for-available-instance"))
+                          healthy-instances (counters/value (metrics/service-counter service-id "instance-counts" "healthy"))
+                          unhealthy-instances (counters/value (metrics/service-counter service-id "instance-counts" "unhealthy"))
+                          failed-instances (counters/value (metrics/service-counter service-id "instance-counts" "failed"))]
+                      (ex-info (str "After " (t/in-seconds (t/millis queue-timeout-ms))
+                                    " seconds, no instance available to handle request."
+                                    (when (and (zero? healthy-instances) (or (pos? unhealthy-instances) (pos? failed-instances)))
+                                      " Check that your service is able to start properly!")
+                                    (when (and (pos? outstanding-requests) (pos? healthy-instances))
+                                      " Check that your service is able to scale properly!"))
+                               {:service-id service-id
+                                :outstanding-requests outstanding-requests
+                                :requests-waiting-to-stream requests-waiting-to-stream
+                                :waiting-for-available-instance waiting-for-available-instance
+                                :slots-assigned (counters/value (metrics/service-counter service-id "instance-counts" "slots-assigned"))
+                                :slots-available (counters/value (metrics/service-counter service-id "instance-counts" "slots-available"))
+                                :slots-in-use (counters/value (metrics/service-counter service-id "instance-counts" "slots-in-use"))
+                                :work-stealing-offers-received (counters/value (metrics/service-counter service-id "work-stealing" "received-from" "in-flight"))
+                                :work-stealing-offers-sent (counters/value (metrics/service-counter service-id "work-stealing" "sent-to" "in-flight"))
+                                :status 503})))
+                  (do
+                    (cid/with-correlation-id cid (app-not-found-fn))
+                    (async/<! (async/timeout 1500))
+                    (recur (inc iterations)))))))))
+      (catch Exception e
+        (cid/cerror cid e "Error in get-available-instance")
+        e)
+      (finally
+        (counters/dec! (metrics/service-counter service-id "request-counts" "waiting-for-available-instance"))
+        (statsd/gauge-delta! metric-group "request_waiting_for_instance" -1)))))

 ;; Create service helpers


Remove unneeded include

Remove unneeded include

--- test/puppetlabs/certificate_authority/core_test.clj
+++ test/puppetlabs/certificate_authority/core_test.clj
@@ -7,8 +7,6 @@
            (javax.net.ssl SSLContext)
            (org.bouncycastle.asn1.x500 X500Name)
            (org.bouncycastle.pkcs PKCS10CertificationRequest)
-           (com.puppetlabs.certificate_authority CertificateAuthority
-                                                 ExtensionsUtils)
            (org.joda.time DateTime Period))
   (:require [clojure.test :refer :all]
             [clojure.java.io :refer [resource reader]]


Remove redundant println

Remove redundant println

--- src/tick/core.cljc
+++ src/tick/core.cljc
@@ -887,8 +887,6 @@
       (apply max (map :tick/end intervals))
       end)))

-`(println "foo")
-
 #?(:clj
    (extend-protocol ITimeSpan
      clojure.lang.APersistentMap


Add channel counts

Add channel counts

--- src/webcv/web.cljs
+++ src/webcv/web.cljs
@@ -46,7 +46,9 @@
         [:button
          {:on-click #(render @ctx @input (partial reset! output))}
          "run"]]
-       [:p (if @ctx "ctx loaded" "ctx not loaded")]
+       [:p (if-let [{::audio/keys [actx]} @ctx]
+             (str "ctx loaded, " (.-maxChannelCount (.-destination actx)) " outs")
+             "ctx not loaded")]
        [:p (with-out-str (pprint (::graph @output)))]])))

 (defn -main []


add tests for split - so I can get nested split working

--- dada-core/src/test/clojure/org/dada/core/test_dql.clj
+++ dada-core/src/test/clojure/org/dada/core/test_dql.clj
@@ -28,6 +28,11 @@
 	value (first (.getExtant (.getData model)))]
     (.get (.getGetter (nth (.getAttributes (.getMetadata model)) 1)) value)))

+(defn split-values [[metadata-fn data-fn]]
+  (let [[metamodel] (data-fn)
+	models (.getExtant (.getData metamodel))]
+    (reduce (fn [result [model path]] (conj result [(map second path) (.getExtant (.getData model))])) {} models)))
+
 ;;--------------------------------------------------------------------------------

 (deftest test-dcount
@@ -38,5 +43,18 @@
   (is (= (reduction-value (? (dsum 4)(dfrom "Whales")))
 	 (reduce (fn [total whale] (+ total (nth whale 4))) 0 whale-data))))

+;; one dimension - a map of [key]:[matching elements...]
+(deftest test-split-1d
+  (is (= (split-values (? (dsplit 2)(dfrom "Whales")))
+	 (group-by (juxt (fn [[id version type]] type)) whale-data))))

+;; 2 dimensions - flat - a map of [key1,key2]:[matching elements...]
+(deftest test-split-1d
+  (is (= (split-values (? (dsplit 3)(dsplit 2)(dfrom "Whales")))
+	 (group-by (juxt (fn [[_ _ type]] type)(fn [[_ _ _ ocean]] ocean)) whale-data))))

+;; 2 dimensions - nested - a map of [key1]:{[key2]:[matching elements...]} - NYI
+;; (deftest test-split-1d
+;;   (is (= (split-values (? (dsplit 3)(dsplit 2)(dfrom "Whales")))
+;; 	 (group-by (juxt (fn [[_ _ type]] type)(fn [[_ _ _ ocean]] ocean)) whale-data))))
+


CMR-6295 reformatted test to be cleaner

CMR-6295 reformatted test to be cleaner

--- system-int-test/test/cmr/system_int_test/search/autocomplete/suggestion_reindex_test.clj
+++ system-int-test/test/cmr/system_int_test/search/autocomplete/suggestion_reindex_test.clj
@@ -2,6 +2,7 @@
   "This tests re-indexes autocomplete suggestions."
   (:require
    [clojure.test :refer :all]
+   [cmr.common.util :as util :refer [are3]]
    [cmr.mock-echo.client.echo-util :as e]
    [cmr.system-int-test.data2.collection :as dc]
    [cmr.system-int-test.data2.core :as d]
@@ -14,25 +15,21 @@
    [cmr.system-int-test.utils.ingest-util :as ingest]
    [cmr.system-int-test.utils.search-util :as search]))

-(use-fixtures :each (join-fixtures
-                      [(ingest/reset-fixture {"provguid1" "PROV1"})
-                       hu/grant-all-humanizers-fixture
-                       hu/save-sample-humanizers-fixture]))

 (defn compare-autocomplete-results
- "Compare expected to actual response for the following:
- - Items are ordered by score in descending order
- - Ensure that the other fields match"
- [actual expected]
- (let [scores (map :score actual)
-       actual-scores-descending? (->> actual
-                                      (map :score)
-                                      (apply >=))
-       ; we don't need to actually compare scores
-       expected (map #(dissoc % :score) expected)
-       actual (map #(dissoc % :score) actual)]
-   (is (true? actual-scores-descending?))
-   (is (= expected actual))))
+  "Compare expected to actual response for the following:
+  - Items are ordered by score in descending order
+  - Ensure that the other fields match"
+  [actual expected]
+  (let [scores (map :score actual)
+        actual-scores-descending? (->> actual
+                                       (map :score)
+                                       (apply >=))
+                                        ; we don't need to actually compare scores
+        expected (map #(dissoc % :score) expected)
+        actual (map #(dissoc % :score) actual)]
+    (is (true? actual-scores-descending?))
+    (is (= expected actual))))

 (def sk1 (umm-spec-common/science-keyword {:Category "Earth science"
                                            :Topic "Topic1"
@@ -72,16 +69,17 @@
              :Fees "None currently"
              :Format "NetCDF-3"}]})

-(deftest reindex-suggestions-test
+(defn autocomplete-reindex-fixture
+  [f]
   (let [coll1 (d/ingest "PROV1"
                         (dc/collection
-                            {:DataCenters [(data-umm-spec/data-center {:Roles ["ARCHIVER"] :ShortName "DOI/USGS/CMG/WHSC"})]
-                             :ArchiveAndDistributionInformation gdf1
-                             :SpatialKeywords ["DC" "Miami"]
-                             :ProcessingLevelId (:ProcessingLevelId (fu/processing-level-id "PL1"))
-                             :Projects [(:Projects (fu/projects "proj1" "PROJ2"))]
-                             :Platforms [(:Platforms (fu/platforms fu/FROM_KMS 2 2 1))]
-                             :ScienceKeywords [(:ScienceKeywords (fu/science-keywords sk1 sk2))]}))
+                         {:DataCenters [(data-umm-spec/data-center {:Roles ["ARCHIVER"] :ShortName "DOI/USGS/CMG/WHSC"})]
+                          :ArchiveAndDistributionInformation gdf1
+                          :SpatialKeywords ["DC" "Miami"]
+                          :ProcessingLevelId (:ProcessingLevelId (fu/processing-level-id "PL1"))
+                          :Projects [(:Projects (fu/projects "proj1" "PROJ2"))]
+                          :Platforms [(:Platforms (fu/platforms fu/FROM_KMS 2 2 1))]
+                          :ScienceKeywords [(:ScienceKeywords (fu/science-keywords sk1 sk2))]}))

         coll2 (fu/make-coll 2 "PROV1"
                             (fu/science-keywords sk1 sk3)
@@ -91,28 +89,46 @@
                             {:DataCenters [(data-umm-spec/data-center {:Roles ["ARCHIVER"] :ShortName "DOI/USGS/CMG/WHSC"})]
                              :ScienceKeywords [(:ScienceKeywords (fu/science-keywords sk1 sk2))]})
         coll3 (d/ingest-concept-with-metadata-file "CMR-6287/C1000000029-EDF_OPS.xml"
-                                                         {:provider-id "PROV1"
-                                                          :concept-type :collection
-                                                          :format-key :echo10})
+                                                   {:provider-id "PROV1"
+                                                    :concept-type :collection
+                                                    :format-key :echo10})
+        _ (index/wait-until-indexed)
+        _ (index/reindex-suggestions)
         _ (index/wait-until-indexed)]
+    (search/get-autocomplete-json "q=boo")
+    (f)))

-    (index/reindex-suggestions)
-    (index/wait-until-indexed)
-    (testing "Ensure that response is in proper format and results are correct"
+(use-fixtures :each (join-fixtures
+                     [(ingest/reset-fixture {"provguid1" "PROV1"})
+                      hu/grant-all-humanizers-fixture
+                      hu/save-sample-humanizers-fixture
+                      autocomplete-reindex-fixture]))
+
+(deftest reindex-suggestions-test
+  (testing "Ensure that response is in proper format and results are correct"
+    (let [results  (get-in (search/get-autocomplete-json "q=level2") [:feed :entry])]
       (compare-autocomplete-results
-        (get-in (search/get-autocomplete-json "q=level2") [:feed :entry])
-        [{:score 0.25604635 :type "organization" :value "Langley DAAC User Services" :fields "Langley DAAC User Services"}
-         {:score 0.041718055 :type "instrument" :value "lVIs" :fields "lVIs"}]))
-    (testing "Ensure science keywords are being indexed properly"
-        (compare-autocomplete-results
-         (get-in (search/get-autocomplete-json "q=solar") [:feed :entry])
-         [{:score 3.4995544, :type "science_keywords", :value "Solar Irradiance", :fields "Sun-Earth Interactions:Solar Activity:Solar Irradiance"}
-          {:score 1.9641972, :type "science_keywords", :value "Solar Irradiance", :fields "Atmosphere:Atmospheric Radiation:Solar Irradiance"}
-          {:score 0.20964509, :type "organization", :value "ACRIM SCF", :fields "ACRIM SCF"}
-          {:score 0.16771607, :type "organization", :value "Langley DAAC User Services", :fields "Langley DAAC User Services"}])
-        (compare-autocomplete-results
-         (get-in (search/get-autocomplete-json "q=solar irradiation") [:feed :entry])
-         [{:score 5.0869484, :type "science_keywords", :value "Solar Irradiance", :fields "Sun-Earth Interactions:Solar Activity:Solar Irradiance"}
-          {:score 2.7943783, :type "science_keywords", :value "Solar Irradiance", :fields "Atmosphere:Atmospheric Radiation:Solar Irradiance"}
-          {:score 0.061936468, :type "organization", :value "ACRIM SCF", :fields "ACRIM SCF"}
-          {:score 0.049549174, :type "organization", :value "Langley DAAC User Services", :fields "Langley DAAC User Services"}]))))
+       results
+       [{:score 0.25604635 :type "organization" :value "Langley DAAC User Services" :fields "Langley DAAC User Services"}
+        {:score 0.041718055 :type "instrument" :value "lVIs" :fields "lVIs"}])))
+
+  (testing "Ensure science keywords are being indexed properly"
+    (are3
+     [query expected]
+     (let [actual (get-in (search/get-autocomplete-json query) [:feed :entry])]
+       (compare-autocomplete-results expected actual))
+
+     "shorter match"
+     "q=solar"
+     [{:score 3.4995544, :type "science_keywords", :value "Solar Irradiance", :fields "Sun-Earth Interactions:Solar Activity:Solar Irradiance"}
+      {:score 1.9641972, :type "science_keywords", :value "Solar Irradiance", :fields "Atmosphere:Atmospheric Radiation:Solar Irradiance"}
+      {:score 0.20964509, :type "organization", :value "ACRIM SCF", :fields "ACRIM SCF"}
+      {:score 0.16771607, :type "organization", :value "Langley DAAC User Services", :fields "Langley DAAC User Services"}]
+
+     "more complete match"
+     "q=solar irradiation"
+     [{:score 5.0869484, :type "science_keywords", :value "Solar Irradiance", :fields "Sun-Earth Interactions:Solar Activity:Solar Irradiance"}
+      {:score 2.7943783, :type "science_keywords", :value "Solar Irradiance", :fields "Atmosphere:Atmospheric Radiation:Solar Irradiance"}
+      {:score 0.061936468, :type "organization", :value "ACRIM SCF", :fields "ACRIM SCF"}
+      {:score 0.049549174, :type "organization", :value "Langley DAAC User Services", :fields "Langley DAAC User Services"}])))
+


fixing unit tests

fixing unit tests

--- test/vignette/http/routes_test.clj
+++ test/vignette/http/routes_test.clj
@@ -90,7 +90,8 @@
                       :middle-dir "35"
                       :top-dir "3"
                       :revision "12345"
-                      :wikia "lotr"} ]
+                      :wikia "lotr"
+                      :options {}} ]
     ((app-routes ..system..) (request :get "/lotr/3/35/ropes.jpg/revision/12345")) => (contains {:status 200})
     (provided
      (store ..system..) => ..store..


handle real userids in websocket

handle real userids in websocket

--- src/cljc/ow/starbuck/impl/websocket.cljc
+++ src/cljc/ow/starbuck/impl/websocket.cljc
@@ -10,37 +10,40 @@
 #?(:clj  (defn- make-sente-channel! [{:keys [userid-fn] :as this}]
            (sente/make-channel-socket! (get-sch-adapter)
                                        (merge {}
-                                              (and userid-fn
-                                                   {:user-id-fn userid-fn}))))
+                                              (and userid-fn {:user-id-fn userid-fn}))))

    :cljs (defn- make-sente-channel! [{:keys [path] :as this}]
            (sente/make-channel-socket! path
                                        {:wrap-recv-evs? false})))

-#?(:clj  (defn- do-send* [{:keys [senteobjs] :as this} [_ msg :as sente-ev]]
-           (let [uid :foo  ;; TODO: use real uid
+#?(:clj  (defn- do-send* [{:keys [senteobjs] :as this} msg]
+           (let [userid (::userid msg)
+                 msg (dissoc msg ::userid)
                  send-fn (:send-fn senteobjs)]
-             (debug "sending message to remote id" uid ":" msg)
-             (send-fn uid sente-ev)))
+             (debug "sending message to remote id" userid ":" msg)
+             (send-fn userid [::message msg])))

-   :cljs (defn- do-send* [{:keys [senteobjs] :as this} [_ msg :as sente-ev]]
+   :cljs (defn- do-send* [{:keys [senteobjs] :as this} msg]
            (go-loop [[i _] [0 nil]]
              (if (< i 100)
                (if (some-> senteobjs :state .-state :open?)
                  (let [send-fn (:send-fn senteobjs)]
                    (debug "sending message to remote:" msg "(try" i ")")
-                   (send-fn sente-ev))
+                   (send-fn [::message msg]))
                  (do (debug "channel not open yet, delaying (try" i "):" msg)
                      (recur [(inc i) (a/<! (a/timeout 500))])))
                (warn "could not send message after 100 tries, aborting:" msg)))))

-(defn- handle-inbound-sentemsg [{:keys [recv-fn] :as this} {:keys [id ?data] :as sentemsg}]
-  (debug "got message from remote:" id ?data)
-  ;;; TODO: add auth checking
-  ;;; TODO: maybe add msg shaping
-  (case id
-    ::message (recv-fn ?data)
-    (warn "unknown message id" id)))
+(defn- handle-inbound-sentemsg [{:keys [recv-fn userid-fn] :as this} {:keys [id ?data ring-req] :as sentemsg}]
+  (let [userid (and userid-fn (userid-fn ring-req))
+        ?data (merge ?data
+                     (and userid {::userid userid}))]
+    (debug "got message from remote:" id ?data)
+    ;;; TODO: add auth checking
+    ;;; TODO: maybe add msg shaping
+    (case id
+      ::message (recv-fn ?data)
+      (warn "unknown message id" id))))

 (defn- start-inbound-msg-handler! [{:keys [senteobjs] :as this}]
   (let [ch-recv (:ch-recv senteobjs)]
@@ -52,8 +55,8 @@

 (defn- do-send [this msg]
   ;;; TODO: maintain queue of pending msgs, to make sure they are sent in the correct order
-  (let [sente-ev [::message (assoc msg :ow.starbuck.routing/tunneled? true)]]
-    (do-send* this sente-ev)))
+  (let [msg (assoc msg :ow.starbuck.routing/tunneled? true)]
+    (do-send* this msg)))

 (defrecord ComponentWebsocket [recv-fn           ;; server & client
                                path              ;; client


Load user.clj if present on classpath

Load user.clj if present on classpath

--- server/src/main/clojure/vimclojure/core.clj
+++ server/src/main/clojure/vimclojure/core.clj
@@ -24,9 +24,11 @@

 (defn init-server
   []
-  ; Check for doc macro. 1.2 in c.core, 1.3 in c.repl
-  (when-not (ns-resolve 'clojure.core 'doc)
-    (binding [*ns* *ns*]
-      (in-ns 'user)
-      (refer-clojure)
-      (use 'clojure.repl))))
+  (binding [*ns* *ns*]
+    (in-ns 'user)
+    (refer-clojure)
+    ; Check for doc macro. 1.2 in c.core, 1.3 in c.repl
+    (when-not (ns-resolve 'clojure.core 'doc)
+      (use 'clojure.repl))
+    (when (io/resource "user.clj")
+      (load "user"))))


cljs.env causing alias error in clojure 1.9 alpha

--- sidecar/src/figwheel_sidecar/system.clj
+++ sidecar/src/figwheel_sidecar/system.clj
@@ -12,8 +12,6 @@

    [strictly-specking-standalone.ansi-util :refer [with-color-when color-text]]
    [com.stuartsierra.component :as component]
-
-   [cljs.env :as env]

    [clojure.pprint :as p]
    [clojure.java.io :as io]


Factor out draw-dome in processing display.

--- dev/org/playasophy/wonderdome/display/processing.clj
+++ dev/org/playasophy/wonderdome/display/processing.clj
@@ -43,7 +43,24 @@
     (quil/ellipse 0 0 radius radius)))

-(defn- draw-pixels
+(defn- draw-dome
+  [radius]
+  (quil/stroke (quil/color 0))
+  (doseq [face geodesic/dome-faces]
+    (-> face
+        (as-> points
+          ; scale the points
+          (map #(vec (map (partial * scale display) %)) points)
+          (vec points)
+          ; repeat the last point
+          (conj points (first points)))
+        line-join-points
+        (as-> lines
+          (map (partial apply quil/line) lines))
+        dorun)))
+
+
+(defn- render
   [display]
   (quil/background 255)
   (quil/translate (* 0.50 (quil/width)) (* 0.55 (quil/height)) 0)
@@ -51,19 +68,8 @@
   #_(quil/rotate-y (* (quil/frame-count) 0.003))
   (draw-axes 150)
   (draw-ground (* scale 20))
-  (quil/stroke (quil/color 0))
-  ; TODO: draw geodesic dome outline
+  (draw-dome (:radius display))
   ; TODO: render pixels
-  (doseq [face geodesic/dome-faces]
-    (-> face
-        (as-> points
-          (map #(vec (map (partial * scale (:radius display)) %)) points)   ; scale the points
-          (vec points)
-          (conj points (first points)))                 ; repeat the last point
-        line-join-points
-        (as-> lines
-          (map (partial apply quil/line) lines))
-        dorun))
   )

@@ -82,7 +88,7 @@
       (quil/sketch
         :title "Playasophy Wonderdome"
         :setup setup-sketch
-        :draw #(draw-pixels this)
+        :draw #(render this)
         :size (:size this)
         :renderer :opengl)))


Prefer 'valid' as the alias for validation.built-ins.

--- clj_record/test/model/manufacturer.clj
+++ clj_record/test/model/manufacturer.clj
@@ -1,6 +1,6 @@
 (ns clj-record.test.model.manufacturer
   (:require clj-record.boot
-            [clj-record.validation.built-ins :as v]
+            [clj-record.validation.built-ins :as valid]
             [clj-record.callbacks.built-ins :as cb])
   (:use clj-record.test.model.config))

@@ -18,9 +18,9 @@
     (has-many products))
   (:validation
     (:name "empty!" #(not (empty? %)))
-    (:name "starts with whitespace!" (v/non-match #"^\s"))
-    (:name "ends with whitespace!" (v/non-match #"\s$"))
-    (:founded "must be numeric" #(or (nil? %) (v/numeric? %)))
+    (:name "starts with whitespace!" (valid/non-match #"^\s"))
+    (:name "ends with whitespace!" (valid/non-match #"\s$"))
+    (:founded "must be numeric" #(or (nil? %) (valid/numeric? %)))
     (:grade my-grade-validation-message #(or (nil? %) (>= % 0))))
   (:callbacks
     (:before-save (cb/transform-value :founded infer-full-year))))


delaney.clj: refactored the (dsymbol) specialisation for class String some more.

--- clojure/org/gavrog/clojure/delaney.clj
+++ clojure/org/gavrog/clojure/delaney.clj
@@ -239,27 +239,31 @@
           rest-free (filter (comp not (set pair)) free)]
       (lazy-seq (cons pair (pairs (rest data) rest-free))))))

+(defn- with-gluings [ds gluings]
+  (reduce (fn [ds i]
+            (reduce (fn [ds [D E]] (glue ds i D E))
+                    ds
+                    (pairs (nth gluings i) (elements ds))))
+          ds
+          (range (count gluings))))
+
+(defn- with-spins [ds spins]
+  (reduce (fn [ds i]
+            (reduce (fn [ds [D v]] (spin ds i (inc i) D v))
+                    ds
+                    (zipmap (orbit-reps ds [i (inc i)]) (nth spins i))))
+          ds
+          (range (count spins))))
+
 (defmethod dsymbol String [code]
   (let [parts (-> code s/trim
                 (s/replace #"^<" "") (s/replace #">$" "") (s/split #":"))
         data (if (re-matches #"\d+.\d+" (first parts)) (rest parts) parts)
-        [size d] (parse-numbers (first data))
-        dim (or d 2)
-        gluings (parse-number-lists (nth data 1))
-        spins (parse-number-lists (nth data 2))
-        d-set (reduce (fn [sym i]
-                        (reduce (fn [ds [D E]] (glue ds i D E))
-                                sym
-                                (pairs (nth gluings i) (range 1 (inc size)))))
-                      (DSymbol. 0 0 {} {})
-                      (range 0 (inc dim)))
-        d-sym (reduce (fn [sym i]
-                        (reduce (fn [ds [D v]] (spin ds i (inc i) D v))
-                                sym
-                                (zipmap (orbit-reps d-set [i (inc i)])
-                                        (nth spins i))))
-                      d-set
-                      (range 0 dim))]
+        [size dim] (parse-numbers (first data))
+        d-set (with-gluings (DSymbol. (or dim 2) size {} {})
+                (parse-number-lists (nth data 1)))
+        d-sym (with-spins d-set
+                (parse-number-lists (nth data 2)))]
     d-sym))

 ;; === Tests


delaney.clj: DSymbol uses dim and size instead of indices, elements lists.

--- clojure/org/gavrog/clojure/delaney.clj
+++ clojure/org/gavrog/clojure/delaney.clj
@@ -27,12 +27,16 @@
   (s [ds i D] (when (.definesOp ds i D) (.op ds i D)))
   (v [ds i j D] (when (.definesV ds i j D) (.v ds i j D))))

-(deftype DSymbol [idcs elms s# v#]
+(deftype DSymbol [dim size s# v#]
   IDSymbol
-  (element? [_ D] (elms D))
-  (elements [_] (seq elms))
-  (index? [_ i] (idcs i))
-  (indices [_] (seq idcs))
+  (element? [_ D] (and (integer? D)
+                       (>= D 1)
+                       (<= D size)))
+  (elements [_] (range 1 (inc size)))
+  (index? [_ i] (and (integer? i)
+                     (>= i 0)
+                     (<= i dim)))
+  (indices [_] (range 0 (inc dim)))
   (s [_ i D] ((or (s# i) {}) D))
   (v [ds i j D]
      (when (and (element? ds D) (index? ds i) (index? ds j))
@@ -42,25 +46,30 @@
              (= (s ds i D) (s ds j D)) 2
              :else 1)))
   IPersistentDSymbol
-  (dsconj [_ new] (DSymbol. idcs (into elms new) s# v#))
+  (dsconj [_ new]
+          (when (and (integer? new) (not (neg? new)))
+            (DSymbol. dim (max size new) s# v#)))
   (dsdisj [_ old]
           (let [s-remove (fn [[i a]]
                            [i (reduce dissoc a (concat old (map (s# i) old)))])
                 v-remove (fn [[i a]] [i (reduce dissoc a old)])
-                new-elms (persistent! (reduce disj! (transient elms) old))
                 new-s# (into {} (map s-remove s#))
                 new-v# (into {} (map v-remove v#))]
-            (DSymbol. idcs new-elms new-s# new-v#)))
+            (DSymbol. dim size new-s# new-v#)))
   (dsglue [ds i D E]
-          (DSymbol. (conj idcs i)
-                    (conj elms D E)
-                    (assoc s# i (assoc (s# i) D E, E D))
-                    v#))
+          (when (and (integer? i) (not (neg? i))
+                     (integer? D) (pos? D)
+                     (integer? E) (pos? E))
+            (DSymbol. (max dim i)
+                      (max size D E)
+                      (assoc s# i (assoc (s# i) D E, E D))
+                      v#)))
   (dsunglue [ds i D]
-            (DSymbol. idcs
-                      elms
-                      (assoc s# i (dissoc (s# i) D ((s# i) D)))
-                      v#))
+            (when (index? ds i)
+              (DSymbol. dim
+                        size
+                        (assoc s# i (dissoc (s# i) D ((s# i) D)))
+                        v#)))
   Object
   (equals [self other]
           (and (satisfies? IDSymbol other)
@@ -71,27 +80,29 @@

 (defmethod print-method DSymbol [ds ^Writer w]
   (print-method (list (symbol "DSymbol.")
-                      (into #{} (indices ds))
-                      (into #{} (elements ds))
+                      (dim ds)
+                      (size ds)
                       (ops ds)
                       (vs ds))
                 w))

 (deftest gluing
-  (is (= (dsglue (DSymbol. #{0 1 2} #{} {} {}) 0 1 2)
-         (DSymbol. #{0 1 2} #{1 2} {0 {1 2 2 1}} {}))))
+  (is (= (dsglue (DSymbol. 0 0 {} {}) 2 1 2)
+         (DSymbol. 2 2 {2 {1 2 2 1}} {}))))

 ;; General D-symbol functions

 (defn- ops [ds]
   (into {} (for [i (indices ds)]
-             [i (into {} (for [D (elements ds)]
+             [i (into {} (for [D (elements ds)
+                               :when (s ds i D)]
                            [D (s ds i D)]))])))

 (defn- vs [ds]
   (into {} (for [i (indices ds)
                  :when (index? ds (inc i))]
-             [i (into {} (for [D (elements ds)]
+             [i (into {} (for [D (elements ds)
+                               :when (v ds i (inc i) D)]
                            [D (v ds i (inc i) D)]))])))

 (defn size [ds] (count (elements ds)))


Focus management #38 - removed hardcoded :z-position from combo box

--- flatguiwidgets/src/flatgui/widgets/combobox.clj
+++ flatguiwidgets/src/flatgui/widgets/combobox.clj
@@ -71,8 +71,6 @@

 (fg/defwidget "combobox"
   { :model []
-    ;; TODO this is temporary just to get combo's dropdown painted on top. Need generic solution.
-    :z-position Integer/MAX_VALUE
     :children {:editor (fg/defcomponent flatgui.widgets.textfield/textfield :editor
                                        {:skin-key [:combobox :editor]
                                         :evolvers {:model combo-text-model-evolver


Add a doall to remove a runtime warning from the webui.

--- metlog-vault/src-client/metlog_client/metlog.cljs
+++ metlog-vault/src-client/metlog_client/metlog.cljs
@@ -122,8 +122,9 @@

 (defn series-list [ ]
   [:div
-   (for [ series (:series @dashboard-state) ]
-     ^{ :key series } [series-pane series @query-window])])
+   (doall
+    (for [ series (:series @dashboard-state) ]
+      ^{ :key series } [series-pane series @query-window]))])

 (defn end-edit [ text state ]
   (when (parse-query-window text)


pings

pings

--- src-cljs/frontend/talaria.cljs
+++ src-cljs/frontend/talaria.cljs
@@ -52,6 +52,7 @@
     (loop [msg (pop-atom send-queue)]
       (when msg
         (send-msg ws msg)
+        (swap! tal-state assoc :last-send-time (js/Date.))
         (recur (pop-atom send-queue))))))

 (defn start-send-queue [tal-state]
@@ -64,8 +65,6 @@
 (defn shutdown-send-queue [tal-state]
   (remove-watch (:send-queue @tal-state) ::send-watcher))

-
-;; XXX: handle callbacks and timeouts
 ;; XXX: handle special messages from the server (ping, close)
 (defn consume-recv-queue [tal-state handler]
   (let [recv-queue (:recv-queue @tal-state)]
@@ -83,16 +82,28 @@
                                              (consume-recv-queue tal-state handler))))
     (consume-recv-queue tal-state handler)))

-(defonce debug-ws (atom nil))
+(defn start-ping [tal-state]
+  (let [ms (:keep-alive-ms @tal-state)]
+    (js/window.setInterval (fn []
+                             (let [last-send (:last-send-time @tal-state)]
+                               (when (or (not last-send)
+                                         (<= (/ ms 2) (- (.getTime (js/Date.)) (.getTime last-send))))
+                                 (queue-msg tal-state {:op :tal/ping}))))
+                           (/ ms 2))))

-(defn init [url & {:keys [on-open on-close on-error]}]
+(defn init
+  "Guaranteed to run keep-alive every keep-alive-ms interval, but may probably run
+   about twice as often"
+  [url & {:keys [on-open on-close on-error keep-alive-ms]
+          :or {keep-alive-ms 60000}}]
+
   (let [ ;; creates class that will handle auto-reconnecting on failure
         w (goog.net.WebSocket.)
-        _ (reset! debug-ws w)
         ch (async/chan (async/sliding-buffer 1024))
         send-queue (atom [])
         recv-queue (atom [])
         tal-state (atom {:ws w
+                         :keep-alive-ms keep-alive-ms
                          :open? false
                          :send-queue send-queue
                          :recv-queue recv-queue
@@ -100,11 +111,14 @@
     (gevents/listen w goog.net.WebSocket.EventType.OPENED
                     #(do
                        (utils/mlog "opened" %)
-                       (swap! tal-state (fn [s]
-                                          (-> s
-                                            (assoc :open? true)
-                                            (dissoc :closed? :close-code :close-reason))))
+                       (let [timer-id (start-ping tal-state)]
+                         (swap! tal-state (fn [s]
+                                            (-> s
+                                              (assoc :open? true
+                                                     :keep-alive-timer timer-id)
+                                              (dissoc :closed? :close-code :close-reason)))))
                        (start-send-queue tal-state)
+
                        (when (fn? on-open)
                          (on-open tal-state))))
     (gevents/listen w goog.net.WebSocket.EventType.CLOSED
@@ -115,6 +129,7 @@
                               :closed? true
                               :close-code (.-code %)
                               :close-reason (.-reason %))
+                       (js/clearInterval (:keep-alive-timer @tal-state))
                        (when (fn? on-close)
                          (on-close tal-state {:code (.-code %)
                                               :reason (.-reason %)}))))
@@ -126,7 +141,7 @@
     (gevents/listen w goog.net.WebSocket.EventType.MESSAGE
                     #(do
                        ;;(utils/mlog "message" %)
-                       (swap! tal-state assoc :last-message-time (js/Date.))
+                       (swap! tal-state assoc :last-recv-time (js/Date.))
                        (swap! recv-queue (fn [q] (apply conj q (decode-msg (.-message %)))))))
     (.open w url)
     tal-state))


added more i18n spec

added more i18n spec

--- spec/untangled/i18n_spec.cljs
+++ spec/untangled/i18n_spec.cljs
@@ -1,5 +1,5 @@
 (ns untangled.i18n-spec
-  (:require-macros [cljs.test :refer (is deftest testing)]
+  (:require-macros [cljs.test :refer (is deftest testing are)]
                    [smooth-spec.core :refer (specification behavior provided assertions)]
                    )
   (:require [untangled.history :as h]
@@ -17,6 +17,21 @@
                (behavior "returns the string it is passed if there is no translation"
                          (is (= "Hello" (trf "Hello")))
                          )
-               (behavior "will accept a sequence of k/v pairs as arguments to the format"
+               (behavior "accepts a sequence of k/v pairs as arguments to the format"
                          (is (= "A 1 B Sam" (trf "A {a} B {name}" :a 1 :name "Sam"))))
+               (behavior "formats numbers"
+                         (is (= "18,349" (trf "{a, number}" :a 18349))))
+               (behavior "formats dates"
+                         (is (= "April 1, 1990" (trf "{a, date, long}" :a (js/Date. 1990 3 1 13 45 22 0))))
+                         (is (= "Apr 1, 1990" (trf "{a, date, medium}" :a (js/Date. 1990 3 1 13 45 22 0))))
+                         (is (= "4/1/90" (trf "{a, date, short}" :a (js/Date. 1990 3 1 13 45 22 0))))
+                         )
+               (behavior "formats plurals"
+                         (are [n msg] (= msg (trf "{n, plural, =0 {no apples} =1 {1 apple} other {# apples}}" :n n))
+                                      0 "no apples"
+                                      1 "1 apple"
+                                      2 "2 apples"
+                                      146 "146 apples"
+                                      )
+                         )
                )


fix "By Repo" branch picker sorting

fix "By Repo" branch picker sorting

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -1,5 +1,6 @@
 (ns frontend.components.aside
   (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer close!]]
+            [clojure.string :refer [lower-case]]
             [frontend.analytics :as analytics]
             [frontend.async :refer [raise!]]
             [frontend.components.common :as common]
@@ -206,7 +207,7 @@
                (om/build branch-list-v2
                          {:branches (->> project
                                          project-model/branches
-                                         (sort-by :name))
+                                         (sort-by (comp lower-case name :identifier)))
                           :show-all-branches? show-all-branches?
                           :navigation-data navigation-data}
                          {:opts {:login login}})]))))


toggle between "Projects" vs "Add Projects" nav items

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -469,27 +469,27 @@
              [:i.material-icons "storage"]
              [:div.nav-label "Builds"]]

-           (when (feature/enabled? :projects-page)
+           [:a.aside-item {:data-placement "right"
+                            :data-trigger "hover"
+                            :title "Insights"
+                            :href "/build-insights"}
+             [:i.material-icons "assessment"]
+             [:div.nav-label "Insights"]]
+
+           (if (feature/enabled? :projects-page)
              [:a.aside-item {:title "Projects"
                              :data-placement "right"
                              :data-trigger "hover"
                              :href "/projects"}
               [:i.material-icons "book"]
-              [:div.nav-label "Projects"]])
-
-            [:a.aside-item {:data-placement "right"
-                            :data-trigger "hover"
-                            :title "Insights"
-                            :href "/build-insights"}
-             [:i.material-icons "assessment"]
-             [:div.nav-label "Insights"]]
-
-            [:a.aside-item {:href "/add-projects",
-                            :data-placement "right"
-                            :data-trigger "hover"
-                            :title "Add Projects"}
-             [:i.material-icons "library_add"]
-             [:div.nav-label "Add Projects"]]
+              [:div.nav-label "Projects"]]
+
+             [:a.aside-item {:href "/add-projects",
+                             :data-placement "right"
+                             :data-trigger "hover"
+                             :title "Add Projects"}
+              [:i.material-icons "library_add"]
+              [:div.nav-label "Add Projects"]])

             [:a.aside-item {:href "/invite-teammates",
                             :data-placement "right"


Change mechanism used to disable elevio

Change mechanism used to disable elevio

--- src-cljs/frontend/elevio.cljs
+++ src-cljs/frontend/elevio.cljs
@@ -9,7 +9,7 @@
 (defn disable! []
   (when-let [el (get-root)]
     (gdom/removeNode el))
-  (aset js/window "_elev" nil))
+  (aset js/window "_elev" #js {}))

 (defn enable! []
   (class-list/add js/document.body "circle-elevio"))


Implement drop keyspace

Implement drop keyspace

--- src/clojure/clojurewerkz/cassaforte/new_query_api.clj
+++ src/clojure/clojurewerkz/cassaforte/new_query_api.clj
@@ -8,7 +8,7 @@
             Clause]
            [com.datastax.driver.core RegularStatement]
            [com.datastax.driver.core.schemabuilder SchemaBuilder SchemaBuilder$Direction
-
+            CreateKeyspace DropKeyspace
             SchemaBuilder$Caching SchemaBuilder$KeyCaching])
   (:require [clojurewerkz.cassaforte.aliases :as alias]
             clojurewerkz.cassaforte.query.query-builder
@@ -580,4 +580,18 @@
 ;; TableOptions.CachingRowsPerPartition allRows()
 ;; TableOptions.CachingRowsPerPartition rows(int rowNumber)

+
+(let [order
+      {:if-exists 1}
+      renderers
+      {:if-exists (fn if-exists [query-builder _]
+                    (.ifExists query-builder))}]
+  (defn drop-keyspace
+    [keyspace-name & statements]
+    (->> statements
+         (sort-by #(get order (first %)))
+         (reduce (fn [builder [statement-name statement-args]]
+                   ((get renderers statement-name) builder statement-args))
+                 (DropKeyspace. (name keyspace-name)))
+         (maybe-stringify))))
 (def ? (QueryBuilder/bindMarker))


Fix class init issue under clojure 1.7.0.

--- core/src/immutant/internal/options.clj
+++ core/src/immutant/internal/options.clj
@@ -69,6 +69,9 @@
 (defn ^java.util.Map opts->map
   "Converts an Option class into a map of name -> Option instance."
   [class]
+  ;; clojure 1.7.0 no longer initializes classes on import, so we have
+  ;; to force init here (see CLJ-1315)
+  (Class/forName (.getName class))
   (->> class
     Option/optsFor
     (map (fn [^Option o] (vector (.name o) o)))


Better formatted output from print-result

--- src/main/clojure/com/stuartsierra/lazytest/report.clj
+++ src/main/clojure/com/stuartsierra/lazytest/report.clj
@@ -39,9 +39,11 @@
   number, doc string, and stack trace if applicable."
   [r]
   (let [m (meta (:source r))]
-    (println (source-name r) (line-and-file r))
+    (println "Test:" (source-name r))
+    (when-let [f (:file m)] (println "File:" f))
+    (when-let [l (:line m)] (println "Line:" l))
     (println "Context states:" (:states r))
-    (print-source-doc r)
+    (when-let [d (source-doc r)] (println "Doc:" d))
     (when-let [e (:error r)]
       (println "STACK TRACE")
       (print-cause-trace e))))


Refactor

Refactor

--- backend/specs/akvo/lumen/specs/visualisation.clj
+++ backend/specs/akvo/lumen/specs/visualisation.clj
@@ -2,20 +2,21 @@
   (:require [akvo.lumen.lib.aggregation :as aggregation]
             [akvo.lumen.lib.aggregation.bar :as aggregation.bar]
             [akvo.lumen.lib.aggregation.bubble :as aggregation.bubble]
-            [akvo.lumen.specs.protocols :as protocols.s]
-            [clojure.tools.logging :as log]
             [akvo.lumen.lib.aggregation.line :as aggregation.line]
             [akvo.lumen.lib.aggregation.pie :as aggregation.pie]
             [akvo.lumen.lib.aggregation.pivot :as aggregation.pivot]
             [akvo.lumen.lib.aggregation.scatter :as aggregation.scatter]
+            [akvo.lumen.lib.visualisation :as visualisation]
             [akvo.lumen.postgres.filter :as postgres.filter]
-            [akvo.lumen.specs.db :as db.s]
             [akvo.lumen.specs :as lumen.s]
             [akvo.lumen.specs.aggregation :as aggregation.s]
+            [akvo.lumen.specs.db :as db.s]
             [akvo.lumen.specs.db.dataset-version :as db.dsv.s]
             [akvo.lumen.specs.db.dataset-version.column :as db.dsv.column.s]
-            [akvo.lumen.lib.visualisation :as visualisation]
-            [clojure.spec.alpha :as s]))
+            [akvo.lumen.specs.protocols :as protocols.s]
+            [akvo.lumen.specs.visualisation.maps :as visualisation.maps.s]
+            [clojure.spec.alpha :as s]
+            [clojure.tools.logging :as log]))

 (s/def ::name string?)
 (s/def ::visualisationType #{"pie" "area" "bar" "line" "polararea" "donut" "pivot table" "scatter" "bubble" "map"})


#19 Warn on reflection is now true by default

--- lambdalf-lib/src/main/clojure/alfresco/core.clj
+++ lambdalf-lib/src/main/clojure/alfresco/core.clj
@@ -17,11 +17,13 @@
     (:import (it.sk.alfresco.clojure ContextHelper)
              (org.alfresco.service ServiceRegistry)))

+(set! *warn-on-reflection* true)
+
 (defn get-bean
   "Yields the instance of a spring managed bean"
   [bean]
   (. (ContextHelper/getApplicationContext) getBean bean))
-
+
 (defn alfresco-services
   []
   (get-bean ServiceRegistry/SERVICE_REGISTRY))


Update mime_type.clj

Update mime_type.clj

Add edn to mimetypes

--- ring-core/src/ring/util/mime_type.clj
+++ ring-core/src/ring/util/mime_type.clj
@@ -25,6 +25,7 @@
    "dms"   "application/octet-stream"
    "doc"   "application/msword"
    "dvi"   "application/x-dvi"
+   "edn"   "application/edn"
    "eot"   "application/vnd.ms-fontobject"
    "eps"   "application/postscript"
    "etx"   "text/x-setext"


update clip2 docs

update clip2 docs

--- src/overtone/sc/machinery/ugen/metadata/binaryopugen.clj
+++ src/overtone/sc/machinery/ugen/metadata/binaryopugen.clj
@@ -122,8 +122,10 @@
    "scale-neg" {:summary "Scale negative part of input wave"
                 :doc "a*b when a < 0, otherwise a."}

-   "clip2" {:summary "Bilateral clipping"
-            :doc "clips input wave a to +/- b"}
+   "clip2" {:args [{:name "input" :doc "Input signal"}
+                   {:name "clip-val" :doc "Max/min val of input signal before clipping is applied"}]
+            :summary "Bilateral clipping"
+            :doc "clips input wave to +/- clip-val"}

    "excess" {:summary "Clipping residual"
              :doc "Returns the difference of the original signal and its clipped form: (a - clip2(a,b))."}
@@ -135,7 +137,7 @@
             :doc "wraps input wave to +/- b"}
    })

-  (def binaryopugen-docspecs
-    (into {} (map
-              (fn [[k v]] [(normalize-ugen-name k) v])
-              unnormalized-binaryopugen-docspecs)))
+(def binaryopugen-docspecs
+  (into {} (map
+            (fn [[k v]] [(normalize-ugen-name k) v])
+            unnormalized-binaryopugen-docspecs)))


Let's see if CI likes this version of the test betterer.

--- integration-tests/src/test/clojure/immutant/integs/jobs.clj
+++ integration-tests/src/test/clojure/immutant/integs/jobs.clj
@@ -42,9 +42,8 @@
       (is (> (:a-value (get-values)) next-value)))))

 (deftest rescheduling
-  (let [initial-value (:another-value (get-values))]
-    (Thread/sleep 1000)
-    (is (> (:another-value (get-values "reschedule")) initial-value))
-    (Thread/sleep 1000)
-    (is (= (:another-value (get-values)) "rescheduled"))))
+  (is (> (:another-value (get-values)) 0))
+  (get-values "reschedule")
+  (Thread/sleep 2000)
+  (is (= (:another-value (get-values)) "rescheduled")))


Note: It was observed that some companies are returning text but not including a Content-Type value.

So, we assume if there is no content-type header that we have text
If there is a content-type header we'll check as before to ensure that it is set to text/plain/.

--- src/ads_txt_crawler/crawl.clj
+++ src/ads_txt_crawler/crawl.clj
@@ -33,11 +33,16 @@
   (if (not (comment-line line))
     (parse-line line)))

-(defn is-text [url headers]
-  (try
+(defn is-text
+  "Do we have a text document.
+
+Note: It was observed that some companies are returning text but not including a Content-Type value.
+So, we assume if there is no content-type header that we have text
+If there is a content-type header we'll check as before to ensure that it is set to text/plain/."
+  [url headers]
+  (if (contains? headers :content-type)
     (clojure.string/starts-with? (:content-type headers) "text/plain")
-    (catch java.lang.NullPointerException e
-      (.println *err* (format "Error: content-type is not text/plain for %s" url)))))
+    true))

 (defn is-error [status]
   (>= status 400))


Minimal go script

Minimal go script

--- src/alphabet_diamond/core.clj
+++ src/alphabet_diamond/core.clj
@@ -1,9 +1,10 @@
-(ns alphabet-diamond.core)
+(ns alphabet-diamond.core
+	(:require [clojure.string :as str :refer [upper-case trim]]))

 (def ^:const row-template "ZYXWVUTSRQPONMLKJIHGFEDCBABCDEFGHIJKLMNOPQRSTUVWXYZ")

 (defn- ucase-letter [letter]
-	(int (.charAt (clojure.string/upper-case letter) 0)))
+	(int (.charAt (upper-case letter) 0)))

 (defn- letter-range [start-letter end-letter]
   (map char (range (int start-letter) (inc (int end-letter)))))
@@ -20,7 +21,7 @@
 	(let [row-number (first row-instructions)
 				letter (second row-instructions)
 				row-letter (nth (letter-range \A (ucase-letter letter)) (- row-number 1))]
-			(clojure.string/replace row-template (re-pattern (str "[^" row-letter "]")) " ")
+			(str/replace row-template (re-pattern (str "[^" row-letter "]")) " ")
 	))

 (defn diamond [letter]
@@ -29,7 +30,7 @@

 (defn check-spec [spec]
 	{:pre [(not (nil? spec))
-				 (re-seq #"^[A-Za-z]$" (clojure.string/trim spec))]}
+				 (re-seq #"^[A-Za-z]$" (trim spec))]}
 		true)

 (defn -main


fix comment

fix comment

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -123,8 +123,9 @@
                             :sem {:pred :be}}})

-           ;; be + propernoun, e.g. "I am John"
-           (let [subj-agr (atom :top)
+           ;; be + propernoun, e.g. "My name is John"
+           (let [gender (atom :top)
+                 number (atom :top)
                  infl (atom :top)
                  the-real-subj (atom :top)
                  the-obj (atom :top)]


yell + PP[at]

yell + PP[at]

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -2070,8 +2070,9 @@
                       :sem {:pred :scrivere}}}

    "yell" {:synsem {:cat :verb
-                    :sem {:pred :yell}}}
-
+                    :sem {:pred :yell}
+                    :subcat {:2 {:cat :prep
+                                 :sem {:pred :at}}}}}
    "you"
    [{:english {:note "♂"}
      :target :it ;; Italian makes gender distinction for agreement with verbs and adjectives..


add (default) rule for intransitive reflexive verbs (e.g. "climb")

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -326,6 +326,19 @@
                              :cat :noun
                              :sem subject-semantics
                              :agr subject-agr}}}}))
+
+   ;; some English verbs e.g. "climb" are reflexive, but without an
+   ;; explicit object, so they have a [:sem :obj], but no [:subcat :2]
+   ;; we want to add a semantic object so that the semantics
+   ;; are the same compared to Italian.
+   (default
+    (let [subject-semantics (atom :top)]
+      {:synsem {:sem {:reflexive true
+                      :subj subject-semantics
+                      :obj subject-semantics}
+                :subcat {:2 '()}}}))
+
+   ;; by default, verbs are intransitive.
    (default
     {:synsem {:cat :verb
               :subcat {:2 {:subcat '()}}}})


add lexical compilation rule for {:modal-with :root}

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -2250,7 +2250,15 @@
                                            :infl :infinitive
                                            :subcat {:1 modal-subject
                                                     :2 '()}}}}}))
-
+                 (default
+                  (let [modal-subject (atom {:cat :noun})]
+                    {:modal-with :root
+                     :synsem {:cat :verb
+                              :subcat {:1 modal-subject
+                                       :2 {:cat :verb
+                                           :infl :root
+                                           :subcat {:1 modal-subject
+                                                    :2 '()}}}}}))

                  ;; prevent :shared-semantics :obj unless it's already set
                  (default


enable "pouvoir"

enable "pouvoir"

--- src/babel/francais/lexicon.clj
+++ src/babel/francais/lexicon.clj
@@ -244,7 +244,7 @@
    (let [common
          {:synsem {:cat :verb
                    :essere false}
-          :français {:futuro-stem "ser"
+          :français {:future-stem "ser"
                      :infinitive "être"
                      :present {:1sing "suis"
                                :2sing "es"
@@ -481,10 +481,9 @@

   "pouvoir"
    (let [shared-part-of-pouvoir
-         {:disable true
-          :synsem {:essere false
+         {:synsem {:essere false
                    :cat :verb}
-          :français {:futuro-stem "pourr"
+          :français {:future-stem "pourr"
                      :drop-e true
                      :past-participle "pu"
                      :imperfect-stem "pouv"
@@ -494,12 +493,12 @@
                                :1plur "pouvons"
                                :2plur "pouvez"
                                :3plur "peuvent"}}}]
-     [(merge shared-part-of-pouvoir
-             {:synsem {:pred :can}})
-      (merge shared-part-of-pouvoir
-             {:synsem {:pred :may}})
-      (merge shared-part-of-pouvoir
-             {:synsem {:pred :be-able-to}})])
+     [(unify shared-part-of-pouvoir
+             {:synsem {:sem {:pred :can}}})
+      (unify shared-part-of-pouvoir
+             {:synsem {:sem {:pred :may}}})
+      (unify shared-part-of-pouvoir
+             {:synsem {:sem {:pred :be-able-to}}})])

   "regarder" [{:synsem {:cat :verb
                         :sem {:pred :look}}}


[victoryw] #N/A reformat

[victoryw] #N/A reformat

--- go-visual/src/go_visual/static_pipeline_instance.clj
+++ go-visual/src/go_visual/static_pipeline_instance.clj
@@ -27,10 +27,10 @@
 (defn statis-pipeline-success-status
   [pipelines]
   (sort-by :counter < (map (fn [pipeline]
-         {:name (:name pipeline)
-          :counter (:counter pipeline)
-          :status  (every? #(and (true? (:scheduled %)) (= (str (:result %)) "Passed")) (:stages pipeline))})
-       pipelines)))
+                            {:name (:name pipeline)
+                             :counter (:counter pipeline)
+                             :status  (every? #(and (true? (:scheduled %)) (= (str (:result %)) "Passed")) (:stages pipeline))})
+                       pipelines)))

 (defn statis-pipeline-continue-failure-counter
   [last-result-failure-counter pipeline-instance]


fix placement of docstring

fix placement of docstring

--- src/brainbot/nozzle/manage.clj
+++ src/brainbot/nozzle/manage.clj
@@ -57,8 +57,9 @@
     (rmq/close ch)
     (rmq/close conn)))

-(defn throw-management-api-error []
+(defn throw-management-api-error
   "throw a somewhat informative message about missing management rights"
+  []
   (throw
    (ex-info
     "no response from RabbitMQ's management API. make sure you have added the management tag for the user in RabbitMQ"


added dar

added dar

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -104,6 +104,12 @@
    ;; TODO: clarify semantics of this in English
    ;;                     "cumplir" {:synsem {:cat :verb
    ;;                                         :sem {:pred :turn-years}}}
+
+
+   "dar" {:espanol  {:present {:1sing "doy"
+                               :2plur "dais"}}
+          :synsem {:cat :verb
+                   :sem {:pred :give}}}

    "deber" {:synsem {:cat :verb
                      :sem {:pred :have-to}}}


don't generate both genders for past perfect unless verb is essere=true

--- src/babel/francais/writer.clj
+++ src/babel/francais/writer.clj
@@ -45,7 +45,8 @@
     ;; for debugging, change (pmap) to (map) so logging is easier to read: in-order rather than interleaved by multiple workers.
     (.size (pmap (fn [verb]
                    (log/trace (str "verb: " (strip-refs verb)))
-                   (let [root-form (get-in verb [:français :français])]
+                   (let [root-form (get-in verb [:français :français])
+                         essere (get-in verb [:synsem :essere])]
                      (log/info (str "generating with verb: '" root-form "'"))
                      (.size (map (fn [tense]
                                    (let [spec (unify {:root {:français {:français root-form}}}
@@ -100,13 +101,14 @@
                                                                    ))
                                                                [:sing :plur]))))
                                                      [:1st :2nd :3rd]))))
-                                           (cond (= tense
-                                                    {:synsem {:sem {:aspect :perfect
-                                                                    :tense :past}}})
-                                                 [{:gender :masc}
-                                                  {:gender :fem}]
-                                                 true
-                                                 [:top])))))
+                                           (cond (and (= true essere)
+                                                      (= tense
+                                                         {:synsem {:sem {:aspect :perfect
+                                                                         :tense :past}}}))
+                                                      [{:gender :masc}
+                                                       {:gender :fem}]
+                                                      true
+                                                      [:top])))))
                                  (list {:synsem {:sem {:tense :conditional}}}
                                        {:synsem {:sem {:tense :future}}}
                                        {:synsem {:sem {:tense :present}}}


Accept also maps for values of :tasks and :subcontexts

--- src/cider_ci/builder/tasks.clj
+++ src/cider_ci/builder/tasks.clj
@@ -60,6 +60,18 @@
            :name (str name-prefix " » " (:name merged-task))
            })))

+
+(defn value-seq-for-map-or-array
+  [mapar]
+  "Accepts a map or any other collection and returns a seq of the values in the
+  first case and the collection itself in the second. Returns an empty array in
+  any other case."
+  (cond
+    (map? mapar) (map second mapar)
+    (coll? mapar) mapar  ; throw this if we do not accept arrays anymore
+    :else [] ))
+
+
 ; build-tasks-for-single-context and build-tasks-for-contexts-sequence
 ; call each other recursively; no need for trampoline, sensible specs
 ; should not blow the stack
@@ -72,9 +84,9 @@
                                task-defaults
                                script-defaults
                                new-name-prefix))
-                 (or (:tasks context) []))
+                 (value-seq-for-map-or-array (:tasks context)))
             (if-let [subcontexts-spec (:subcontexts context)]
-              (build-tasks-for-contexts-sequence subcontexts-spec
+              (build-tasks-for-contexts-sequence (value-seq-for-map-or-array subcontexts-spec)
                                                  task-defaults
                                                  script-defaults
                                                  new-name-prefix)


Revert "Stop trying to convert Java maps, etc to clj"

This reverts commit dc7f2cf41d857c4fdbda90107f41bdf41eb9fd3f.

--- src/clinvar_submitter/core.clj
+++ src/clinvar_submitter/core.clj
@@ -60,10 +60,18 @@
                                (if (instance? List r) (some #(= % v) r) (= r v))))  m)
             (when (= v (ld-> t m ks)) m))))

+(defn convert-jsonld
+  "Convert java structures from jsonld library into clojure structures"
+  [m]
+  (walk/postwalk (fn [n] (cond
+                           (instance? Map n) (into {} n)
+                           (instance? List n) (into [] n)
+                           :else n)) m))
+
 (defn construct-symbol-table
   [coll]
   (let [graph (into [] (get coll "@graph"))]
-    (reduce (fn [acc v] (assoc acc (.get v "id") v)) {} graph)))
+    (reduce (fn [acc v] (assoc acc (.get v "id") (convert-jsonld v))) {} graph)))

 (defn flatten-interpretation
   []