Fixed mis-titled feed link in the header.

--- lambda-blog/src/lambda_blog/templates/page.clj
+++ lambda-blog/src/lambda_blog/templates/page.clj
@@ -27,7 +27,7 @@
              (css path-to-root stylesheets)
              (html/link {:rel :alternate
                          :type (:type feed)
-                         :title (str " Feed")
+                         :title (str title " Feed")
                          :href (pathcat path-to-root (:path feed))})
              (html/link {:rel :icon
                          :type "image/png"


Moved tag cloud inside of a inline list.

--- lambda-blog/src/lambda_blog/templates/tags.clj
+++ lambda-blog/src/lambda_blog/templates/tags.clj
@@ -2,7 +2,7 @@
   (:require [lambda-blog.templates.bits :refer [panel text-centered]]
             [lambda-blog.templates.page :refer [page]]
             [lambda-blog.utils :refer [pathcat]]
-            [s-html.tags :refer [a div h1 span]]))
+            [s-html.tags :refer [a h1 li span ul]]))

 (defn tag-cloud
   "Creates a tag cloud of `tags` where each element is scaled according to the number of `entries` that are tagged by it. `min` and `max` specify in percent the minimal and maximal font size of the elements."
@@ -16,19 +16,20 @@
                                count
                                (vector %))))
         total (count entries)]
-    (div (text-centered
-          (map (fn [[t c]]
-                 (a {:class :tag
-                     :href (pathcat path-to-root (:path t))}
-                    (span {:class [:label :label-info]
-                           :style (format "font-size: %s%%;"
-                                          (int (+ min
-                                                  (* (- max min)
-                                                     (/ c total)))))}
-                          (:id t))
-                    " "))
-               (sort-by (comp :id first)
-                        counts))))))
+    (text-centered
+     (ul {:class :list-inline}
+         (map (fn [[t c]]
+                (li (a {:class :tag
+                        :href (pathcat path-to-root (:path t))}
+                       (span {:class [:label :label-info]
+                              :style (format "font-size: %s%%;"
+                                             (int (+ min
+                                                     (* (- max min)
+                                                        (/ c total)))))}
+                             (:id t))
+                       " ")))
+              (sort-by (comp :id first)
+                       counts))))))

 (defn tags-index
   "Creates an HTML page containing a [[tag-cloud]]."


adding test structure for all the player methods

--- clj/test/limelight/casting_director_test.clj
+++ clj/test/limelight/casting_director_test.clj
@@ -6,15 +6,20 @@
     [limelight.prop :only (new-prop)]
     [limelight.production :only (new-production)]
     [limelight.test-help :only (fake-fs *fs*)]
-    [lazytest.describe :only (describe testing it with given)]
+    [lazytest.describe :only (describe testing it with given do-it)]
     [lazytest.context :only (fn-context)])
   (:import [limelight.casting-director CastingDirector]))

-(defn setup-prop [options]
+(defn setup-scene []
   (let [production (new-production (limelight.model.FakeProduction. "MockProduction"))
         scene (new-scene {:path "root"})
         _ (.setCastingDirector @(.peer scene) (limelight.model.api.FakeCastingDirector.))
-        _ (.setProduction @(.peer scene) (.peer production))
+        _ (.setProduction @(.peer scene) (.peer production))]
+    scene))
+
+
+(defn setup-prop []
+  (let [scene (setup-scene)
         [prop] (add-props scene (new-prop {}))]
     [prop scene]))

@@ -23,10 +28,17 @@
     (doall (map (fn [[filename content]] (.createTextFile fs filename content)) options))
     fs))

+(defn actions-for [prop event]
+  (-> prop
+    (.peer)
+    (deref)
+    (.getEventHandler)
+    (.getActions event)))
+
 (describe "CastingDirector"

   (testing "creation"
-    (given [scene (new-scene {})
+    (given [scene (new-scene {})
             casting-director (new-casting-director scene)]
       (it "has en empty cast" (= {} @(.cast casting-director)))))

@@ -35,25 +47,30 @@

   (testing "includes one player from scene"
     (given [fs (setup-fs {"/root/players/test_player.clj" "(on-mouse-clicked (fn [_]))"})
-            [prop scene] (setup-prop {})
+            [prop scene] (setup-prop)
             casting-director (new-casting-director scene)
             _ (.castPlayer casting-director prop "test-player")]
-      (it (= 1 (-> prop
-        (.peer)
-        (deref)
-        (.getEventHandler)
-        (.getActions limelight.ui.events.panel.MouseClickedEvent)
-        (count))))))
+      (it (= 1 (count (actions-for prop limelight.ui.events.panel.MouseClickedEvent))))))

   (testing "includes one player from production"
     (given [fs (setup-fs {"/MockProduction/players/test_player.clj" "(on-mouse-clicked (fn [_]))"})
-            [prop scene] (setup-prop {})
+            [prop scene] (setup-prop)
             casting-director (new-casting-director scene)
             _ (.castPlayer casting-director prop "test-player")]
-      (it (= 1 (-> prop
-        (.peer)
-        (deref)
-        (.getEventHandler)
-        (.getActions limelight.ui.events.panel.MouseClickedEvent)
-        (count))))))
-  )
+      (it (= 1 (count (actions-for prop limelight.ui.events.panel.MouseClickedEvent)))))))
+
+;(doseq [[event name] {limelight.ui.events.panel.MouseClickedEvent "mouse-clicked"
+;                      limelight.ui.events.panel.MousePressedEvent "mouse-pressed"}]
+  (describe "Player Events"
+    (given [fs (setup-fs {})
+            scene (setup-scene)
+            casting-director (new-casting-director scene)]
+      (testing "mouse clicked"
+        (given [_ (.createTextFile fs "/MockProduction/players/test_player.clj" "(on-mouse-clicked (fn [_] (def *message* \"mouse-clicked\")))")
+                [prop] (add-props scene (new-prop {}))
+                _ (.castPlayer casting-director prop "test-player")
+                actions (actions-for prop limelight.ui.events.panel.MouseClickedEvent)]
+          (it "has a mouse-clicked action" (= 1 (count actions)))
+          (it "executes actions without exception" (try (doseq [action actions] (.invoke action nil)) true (catch Exception e false)))
+          (it "is the action we added" (= "mouse-clicked" @(ns-resolve (@(.cast casting-director) "test-player") '*message*)))))))
+;)


Fix dummy test

Fix dummy test

--- test/lambdaui/core_test.clj
+++ test/lambdaui/core_test.clj
@@ -3,5 +3,5 @@
             [lambdaui.core :refer :all]))

 (deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))
+  (testing "I am a dummy test"
+    (is (= 1 1))))


Add better test for pubsub socket type.

Add better test for pubsub socket type.

--- test/nanomsg/core_tests.clj
+++ test/nanomsg/core_tests.clj
@@ -87,35 +87,20 @@
       (is (= result2 [true false]))
       (is (= result1 [false true])))))

+(deftest socket-pub-sub
+  (with-open [sock (nn/socket :pub)]
+    (nn/bind! sock s-bind-ipc)

-;; (deftest socket-pub-sub
-;;   (let [p1 (promise)
-;;         p2 (promise)]
+    (let [f1 (future
+               (with-open [sock (nn/socket :sub)]
+                 (nn/connect! sock s-bind-ipc)
+                 (nn/subscribe! sock (into-array Byte/TYPE [1]))
+                 (nn/recv! sock)))]

-;;     (future
-;;       (with-open [sock (nn/socket :sub)]
-;;         (nn/connect! sock s-bind-ipc)
-;;         (nn/subscribe! sock (into-array Byte/TYPE [1]))
-;;         (let [received (nn/recv! sock)]
-;;           (deliver p1 received))))
-
-;;     ;; (future
-;;     ;;   (with-open [sock (nn/socket :sub)]
-;;     ;;     (nn/connect! sock s-bind-ipc)
-;;     ;;     (nn/subscribe! sock (into-array Byte/TYPE [0]))
-;;     ;;     (let [received (nn/recv! sock)]
-;;     ;;       (deliver p2 received))))
-;;     (Thread/sleep 1000)
-;;     (with-open [sock (nn/socket :pub)]
-;;       (nn/bind! sock s-bind-ipc)
-;;       (nn/send! sock (into-buffer spec1 [true false])))
-
-;;     (let [buffer1 (deref p1)
-;;           ;; buffer2 (deref p2)
-;;           result1 (buf/read buffer1 spec1)]
-;;           ;; result2 (buf/read buffer2 spec1)]
-;;       (is (= result1 [true false])))))
-;;       ;; (is (= result2 [false true])))))
+      (nn/send! sock (into-buffer spec1 [true false]))
+      (let [buffer @f1
+            result (buf/read buffer spec1)]
+        (is (= result [true false]))))))

 (deftest socket-bus
   (let [p1 (promise)
@@ -141,5 +126,3 @@
           result2 (buf/read buffer2 spec1)]
       (is (= result1 [false true]))
       (is (= result2 [false true])))))
-
-


Update nomenclature in cross-paraboloid Function

--- cortex/src/cortex/optimize/functions.clj
+++ cortex/src/cortex/optimize/functions.clj
@@ -10,27 +10,27 @@
   (gradient [this params] ((:gradient this) params)))

 (def cross-paraboloid
-  "Depending on the number of args passed to it, generates
+  "Depending on the length of the parameter vector, generates
   functions of the form:

   f(x, y) = (x + y)² + (y + x)²
   f(x, y, z) = (x + y)² + (y + z)² + (z + x)²
   f(x, y, z, w) = (x + y)² + (y + z)² + (z + w)² + (w + x)²"
-  {:value (fn [args]
-            (->> args
+  {:value (fn [params]
+            (->> params
               vec
               cycle
-              (take (inc (m/ecount args)))
+              (take (inc (m/ecount params)))
               (partition 2 1)
               (map (partial apply +))
               (map m/square)
               (apply +)))
-   :gradient (fn [args]
-               (->> args
+   :gradient (fn [params]
+               (->> params
                  vec
                  cycle
-                 (drop (dec (m/ecount args)))
-                 (take (+ 3 (dec (m/ecount args))))
+                 (drop (dec (m/ecount params)))
+                 (take (+ 3 (dec (m/ecount params))))
                  (partition 3 1)
                  (map (partial map * [2 4 2]))
                  (map (partial apply +))


Change up the server tests to use deftrackedapp

--- test/picard/test/server.clj
+++ test/picard/test/server.clj
@@ -151,13 +151,7 @@
        :request [(includes-hdrs {"connection" "close"}) nil])))

 (defcoretest aborting-a-request
-  [ch]
-  (fn [resp request]
-    (enqueue ch [:request request])
-    (fn [evt val]
-      (enqueue ch [evt val])
-      (when (= :done evt)
-        (resp [200 {"connection" "close"} "Hello"]))))
+  (tracking-middleware hello-world-app)

   (http-write "POST / HTTP/1.1\r\n"
               "Content-Length: 10000\r\n\r\n"
@@ -170,9 +164,7 @@
        :abort   nil)))

 (defcoretest applications-raising-errors
-  [ch]
-  (fn [resp request]
-    (enqueue ch [:request request])
+  (deftrackedapp [upstream request]
     (throw (Exception. "TROLL APP IS TROLLIN'")))

   (http-write "GET / HTTP/1.1\r\n\r\n")
@@ -181,7 +173,6 @@
   (is (= 0 (count (netty-exception-events)))))

 (defcoretest upstream-raising-error-during-chunked-request
-  [ch]
   (fn [upstream request]
     (throw (Exception. "TROLL APP IS TROLLIN'")))

@@ -212,18 +203,15 @@
   (http-write (apply str (for [x (range 10000)] "a"))))

 (defcoretest telling-the-application-to-chill-out
-  [ch]
-  (fn [resp request]
-    (enqueue ch [:request request])
-    (resp :response [200 {"transfer-encoding" "chunked"} :chunked])
+  (deftrackedapp [upstream request]
+    (upstream :response [200 {"transfer-encoding" "chunked"} :chunked])
     ;; The latch will let us pause
     (let [latch (atom true)]
-      (bg-while @latch (resp :body "HAMMER TIME!"))
+      (bg-while @latch (upstream :body "HAMMER TIME!"))
       (fn [evt val]
-        (enqueue ch [evt val])
         (when (= :pause evt) (toggle! latch))
         (when (= :resume evt)
-          (resp :done nil)))))
+          (upstream :done nil)))))

   ;; Now the tests
   (http-write "GET / HTTP/1.1\r\n"
@@ -235,14 +223,11 @@
        :resume  nil)))

 (defcoretest raising-error-during-pause-event
-  [ch]
-  (fn [resp request]
-    (enqueue ch [:request request])
+  (deftrackedapp [upstream request]
     (let [latch (atom true)]
-      (resp :response [200 {"transfer-encoding" "chunked"} :chunked])
-      (bg-while @latch (resp :body "HAMMER TIME!"))
+      (upstream :response [200 {"transfer-encoding" "chunked"} :chunked])
+      (bg-while @latch (upstream :body "HAMMER TIME!"))
       (fn [evt val]
-        (enqueue ch [evt val])
         (when (= :pause evt)
           (swap! latch (fn [_] false))
           (throw (Exception. "fail"))))))
@@ -260,14 +245,11 @@
   (is (not-receiving-messages)))

 (defcoretest raising-error-during-resume-event
-  [ch]
-  (fn [resp request]
-    (enqueue ch [:request request])
+  (deftrackedapp [upstream request]
     (let [latch (atom true)]
-      (resp :response [200 {"transfer-encoding" "chunked"} :chunked])
-      (bg-while @latch (resp :body "HAMMER TIME!"))
+      (upstream :response [200 {"transfer-encoding" "chunked"} :chunked])
+      (bg-while @latch (upstream :body "HAMMER TIME!"))
       (fn [evt val]
-        (enqueue ch [evt val])
         (when (= :pause evt) (toggle! latch))
         (when (= :resume evt)
           (throw (Exception. "fail"))))))
@@ -286,18 +268,16 @@
   (is (not-receiving-messages)))

 (defcoretest telling-the-server-to-chill-out
-  [ch ch2]
-  (fn [resp request]
+  [_ ch2]
+  (deftrackedapp [upstream request]
     (receive-all
      ch2
-     (fn [_] (resp :resume nil)))
-    (enqueue ch [:request request])
-    (resp :pause nil)
+     (fn [_] (upstream :resume nil)))
+    (upstream :pause nil)
     (fn [evt val]
-      (enqueue ch [evt val])
       (when (= :done evt)
-        (resp :response [200 {"content-type" "text/plain"
-                              "content-length" "5"} "Hello"]))))
+        (upstream :response [200 {"content-type" "text/plain"
+                                  "content-length" "5"} "Hello"]))))

   ;; Now some tests
   (http-write "POST / HTTP/1.1\r\n"
@@ -317,14 +297,11 @@
        :done nil)))

 (defcoretest handling-100-continue-requests-with-100-response
-  [ch]
-  (fn [upstream request]
-    (enqueue ch [:request request])
+  (deftrackedapp [upstream request]
     (upstream :response [100])
     (fn [evt val]
-      (enqueue ch [evt val])
       (when (= :done evt)
-        (upstream :response [200 {"content-length" "5"} "Hello"]))))
+        (upstream :response [200 {"content-ength" "5"} "Hello"]))))

   (http-write "POST / HTTP/1.1\r\n"
               "Content-Length: 5\r\n"
@@ -344,11 +321,9 @@
        :done nil)))

 (defcoretest handling-100-continue-requests-by-responding-directly
-  [ch]
-  (fn [upstream request]
-    (enqueue ch [:request request])
+  (deftrackedapp [upstream request]
     (upstream :response [417 {"content-length" "0"}])
-    (fn [evt val] (enqueue ch [evt val])))
+    (fn [_ _]))

   (http-write "POST / HTTP/1.1\r\n"
               "Content-Length: 5\r\n"
@@ -391,11 +366,8 @@
        "connection: close\r\n\r\n")))

 (defcoretest client-sends-body-and-expects-100
-  [ch]
-  (fn [upstream request]
-    (enqueue ch [:request request])
+  (deftrackedapp [upstream request]
     (fn [evt val]
-      (enqueue ch [evt val])
       (when (= :done evt)
         (upstream :response [204 {"connection" "close"}]))))


deftest -> fact, due to bug in lucid.publish

--- libs/axiom-cljs/test/axiom_cljs/core_test.cljs
+++ libs/axiom-cljs/test/axiom_cljs/core_test.cljs
@@ -459,7 +459,7 @@
 We use [reagent-query](https://github.com/brosenan/reagent-query) for querying the generated UI.
 We start with an empty task-list.
 We expect to see a `:div` containing a `:h2` with the user's name."
-(deftest test1
+(fact test1
   (let [host (ax/mock-connection "foo")
         ui (tasks-editor host)]
     (is (= (rq/query ui :div :h2) ["foo's Tasks"]))))
@@ -476,7 +476,7 @@
     (add {:ts 2000
           :task "Two"})))

-(deftest test2
+(fact test2
   (let [host (ax/mock-connection "foo")]
     (add-two-tasks host)
     (let [ui (tasks-editor host)]
@@ -485,7 +485,7 @@
       (is (= (rq/query ui :div :ul :li :button) ["Done" "Done"])))))

 "The button's `:on-click` handler removes an item from the list."
-(deftest test3
+(fact test3
   (let [host (ax/mock-connection "foo")]
     (add-two-tasks host)
     (let [ui (tasks-editor host)
@@ -496,7 +496,7 @@
       (is (= (rq/query (tasks-editor host) :div :ul :li :input:value) ["Two"])))))

 "The `:input` box's `:on-change` event updates the task."
-(deftest test4
+(fact test4
   (let [host (ax/mock-connection "foo")]
     (add-two-tasks host)
     (let [ui (tasks-editor host)
@@ -505,9 +505,8 @@
       ((second updaters) (rq/mock-change-event "Three"))
       ;; The "Two" value became "Three"
       (is (= (rq/query (tasks-editor host) :div :ul :li :input:value) ["One" "Three"])))))
-
 "A \"New Task\" button creates a new, empty task."
-(deftest test5
+(fact test5
   (let [host (-> (ax/mock-connection "foo")
                  (assoc :time (constantly 555)))]
     (let [ui (tasks-editor host)]


CMR-3551: Added Integration tests.

CMR-3551: Added Integration tests.

--- system-int-test/test/cmr/system_int_test/ingest/granule_parent_dependency_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/granule_parent_dependency_test.clj
@@ -40,6 +40,204 @@
 ;; two-d-coordinate-system - start-coordinate-1, end-coordinate-1, start-coordinate-2, end-coordinate-2
 ;; must fall within bounds defined in parent collection

+;; This test demonstrates how granule's platform references the collection's platform and
+;; the platform aliases defined in the humanizer.
+(deftest granule-match-parent-collection-platform-alias-test
+  (let [psa1 (dc/psa {:name "a-float" :data-type :float :min-value 1.0 :max-value 10.0})
+        gpsa (dg/psa "a-float" [7.0])
+        projects (dc/projects "proj")
+        mbr1 (umm-s/set-coordinate-system :geodetic (m/mbr 10 10 20 0))
+        gran-spatial-rep (apply dg/spatial [mbr1])
+        two-d-cs {:name "BRAVO"
+                  :coordinate-1 {:min-value 100
+                                 :max-value 200}
+                  :coordinate-2 {:min-value 300
+                                 :max-value 400}}
+        g-two-d-cs (dg/two-d-coordinate-system
+                     {:name "BRAVO"
+                      :start-coordinate-1 110
+                      :end-coordinate-1 130
+                      :start-coordinate-2 300
+                      :end-coordinate-2 328})
+
+        i1 (dc/instrument {:short-name "instrumentA"})
+        ir1 (dg/instrument-ref {:short-name "instrumentA"})
+        i2 (dc/instrument {:short-name "instrumentB"})
+        ir2 (dg/instrument-ref {:short-name "instrumentB"})
+
+        c-p1 (dc/platform {:short-name "Terra" :instruments [i1]})
+        c-p2 (dc/platform {:short-name "Foo"})
+        c-p3 (dc/platform {:short-name "AM-1" :instruments [i2]})
+
+        g-pr1 (dg/platform-ref {:short-name "Terra"})
+        g-pr2 (dg/platform-ref {:short-name "Terra" :instrument-refs [ir1]})
+        g-pr3 (dg/platform-ref {:short-name "Terra" :instrument-refs [ir2]})
+        g-pr4 (dg/platform-ref {:short-name "Foo"})
+        g-pr5 (dg/platform-ref {:short-name "AM-1"})
+        g-pr6 (dg/platform-ref {:short-name "AM-1" :instrument-refs [ir1]})
+        g-pr7 (dg/platform-ref {:short-name "AM-1" :instrument-refs [ir2]})
+        g-pr8 (dg/platform-ref {:short-name "Bar"})
+
+        coll-data1 {:entry-title "short_name1_version"
+                    :short-name "short_name1"
+                    :version-id "version"
+                    :product-specific-attributes [psa1]
+                    :platforms [c-p1 c-p2]
+                    :organizations [(dc/org :distribution-center "Larc")]
+                    :science-keywords [(dc/science-keyword {:category "upcase"
+                                                            :topic "Cool"
+                                                            :term "Mild"})]
+                    :projects projects
+                    :spatial-coverage (dc/spatial {:gsr :geodetic})
+                    :two-d-coordinate-systems [two-d-cs]
+                    :related-urls [(dc/related-url {:type "type" :url "htt://www.foo.com"})]
+                    :beginning-date-time "1965-12-12T07:00:00.000-05:00"
+                    :ending-date-time "1967-12-12T07:00:00.000-05:00"}
+
+       coll-data2 {:entry-title "short_name2_version"
+                   :short-name "short_name2"
+                   :version-id "version"
+                   :product-specific-attributes [psa1]
+                   :platforms [c-p1 c-p3]
+                   :organizations [(dc/org :distribution-center "Larc")]
+                   :science-keywords [(dc/science-keyword {:category "upcase"
+                                                           :topic "Cool"
+                                                           :term "Mild"})]
+                   :projects projects
+                   :spatial-coverage (dc/spatial {:gsr :geodetic})
+                   :two-d-coordinate-systems [two-d-cs]
+                   :related-urls [(dc/related-url {:type "type" :url "htt://www.foo.com"})]
+                   :beginning-date-time "1965-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-12-12T07:00:00.000-05:00"}
+
+       gran-data1 {:platform-refs [g-pr1]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        gran-data2 {:platform-refs [g-pr2]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        gran-data3 {:platform-refs [g-pr3]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        gran-data4 {:platform-refs [g-pr4]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        gran-data5 {:platform-refs [g-pr5]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        gran-data6 {:platform-refs [g-pr6]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        gran-data7 {:platform-refs [g-pr7]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        gran-data8 {:platform-refs [g-pr8]
+                   :spatial-coverage gran-spatial-rep
+                   :two-d-coordinate-system g-two-d-cs
+                   :product-specific-attributes [gpsa]
+                   :beginning-date-time "1966-12-12T07:00:00.000-05:00"
+                   :ending-date-time "1967-10-12T07:00:00.000-05:00"}
+
+        echo10-coll1 (dc/collection coll-data1)
+        _ (d/ingest "PROV1" echo10-coll1 {:format :echo10})
+        echo10-coll2 (dc/collection coll-data2)
+        _ (d/ingest "PROV1" echo10-coll2 {:format :echo10})
+
+        gran-Terra-coll1 (dg/granule echo10-coll1 gran-data1)
+        gran-AM-1-coll1 (dg/granule echo10-coll1 gran-data5)
+        gran-Foo-coll1 (dg/granule echo10-coll1 gran-data4)
+        gran-Bar-coll1 (dg/granule echo10-coll1 gran-data8)
+        gran-AM-1-InstrumentA-coll1 (dg/granule echo10-coll1 gran-data6)
+
+        gran-Terra-coll2 (dg/granule echo10-coll2 gran-data1)
+        gran-AM-1-coll2 (dg/granule echo10-coll2 gran-data5)
+        gran-AM-1-InstrumentA-coll2 (dg/granule echo10-coll2 gran-data6)
+        gran-AM-1-InstrumentB-coll2 (dg/granule echo10-coll2 gran-data7)
+        gran-Terra-InstrumentA-coll2 (dg/granule echo10-coll2 gran-data2)
+        gran-Terra-InstrumentB-coll2 (dg/granule echo10-coll2 gran-data3)
+        gran-Foo-coll2 (dg/granule echo10-coll2 gran-data4)]
+
+    (are3 [exp-errors gran]
+          (is (= exp-errors
+                 (flatten (map (fn [error] (:errors error))
+                               (:errors (d/ingest "PROV1" gran {:format :echo10 :allow-failure? true}))))))
+
+          "gran-Terra-coll1 success test"
+          []
+          gran-Terra-coll1
+
+          "gran-AM-1-coll1 success test"
+          []
+          gran-AM-1-coll1
+
+          "gran-Foo-coll1 success test"
+          []
+          gran-Foo-coll1
+
+          "gran-AM-1-InstrumentA-coll1 success test"
+          []
+          gran-AM-1-InstrumentA-coll1
+
+          "gran-Bar-coll1 failure test"
+          ["The following list of Platform short names did not exist in the referenced parent collection: [Bar]."]
+          gran-Bar-coll1
+
+          "gran-Terra-coll2 success test"
+          []
+          gran-Terra-coll2
+
+          "gran-AM-1-coll2 success test"
+          []
+          gran-AM-1-coll2
+
+          "gran-AM-1-InstrumentA-coll2 success test"
+          []
+          gran-AM-1-InstrumentA-coll2
+
+          "gran-AM-1-InstrumentB-coll2 success test"
+          []
+          gran-AM-1-InstrumentB-coll2
+
+          "gran-Terra-InstrumentA-coll2 success test"
+          []
+          gran-Terra-InstrumentA-coll2
+
+          "gran-Terra-InstrumentB-coll2 failure test"
+          ["The following list of Instrument short names did not exist in the referenced parent collection: [instrumentB]."]
+          gran-Terra-InstrumentB-coll2
+
+          "gran-Foo-coll2 failure test"
+          ["The following list of Platform short names did not exist in the referenced parent collection: [Foo]."]
+          gran-Foo-coll2)))
+
 ;; This tests demonstrates limitations of various collection formats because they do not support
 ;; fields referenced by a child granule.
 (deftest granule-match-parent-collection-test
@@ -47,9 +245,8 @@
         gpsa (dg/psa "a-float" [7.0])
         i1 (dc/instrument {:short-name "instrument-Sn A"})
         ir1 (dg/instrument-ref {:short-name "instrument-Sn A"})
-        p1 (dc/platform {:short-name "teRRa" :instruments [i1]})
-        pr1 (dg/platform-ref {:short-name "AM-1" :instrument-refs [ir1]})
-        pr2 (dg/platform-ref {:short-name "teRRa" :instrument-refs [ir1]})
+        p1 (dc/platform {:short-name "platform-Sn A" :instruments [i1]})
+        pr1 (dg/platform-ref {:short-name "platform-Sn A" :instrument-refs [ir1]})
         projects (dc/projects "proj")
         mbr1 (umm-s/set-coordinate-system :geodetic (m/mbr 10 10 20 0))
         gran-spatial-rep (apply dg/spatial [mbr1])
@@ -85,12 +282,6 @@
                    :product-specific-attributes [gpsa]
                    :beginning-date-time "1966-12-12T07:00:00.000-05:00"
                    :ending-date-time "1967-10-12T07:00:00.000-05:00"}
-        gran-data2 {:platform-refs [pr2]
-                    :spatial-coverage gran-spatial-rep
-                    :two-d-coordinate-system g-two-d-cs
-                    :product-specific-attributes [gpsa]
-                    :beginning-date-time "1966-12-12T07:00:00.000-05:00"
-                    :ending-date-time "1967-10-12T07:00:00.000-05:00"}
         echo10-coll (dc/collection coll-data)
         _ (d/ingest "PROV1" echo10-coll {:format :echo10})
         dif-coll (dc/collection (assoc coll-data :entry-title "short_name2_version"
@@ -110,7 +301,6 @@
                                             :entry-id "short_name5_version"))
         _ (d/ingest "PROV1" iso-smap-coll {:format :iso-smap})
         gran-for-echo10-coll (dg/granule echo10-coll gran-data)
-        gran-for-echo10-coll2 (dg/granule echo10-coll gran-data2)
         gran-for-dif-coll (dg/granule dif-coll gran-data)
         gran-for-dif10-coll (dg/granule dif10-coll gran-data)
         gran-for-iso19115-coll (dg/granule iso19115-coll gran-data)
@@ -120,14 +310,9 @@
           (is (= exp-errors
                  (flatten (map (fn [error] (:errors error))
                                (:errors (d/ingest "PROV1" gran {:format :echo10 :allow-failure? true}))))))
-
-          "ECHO10 collection-referencing the platform alias"
+          "ECHO10 collection"
           []
           gran-for-echo10-coll
-
-          "ECHO10 collection"
-          []
-          gran-for-echo10-coll2

           "DIF collection"
           ["The following list of 2D Coordinate System names did not exist in the referenced parent collection: [BRAVO]."]


CMR-8064: Add support for bearer prefix in authorization header to mo… (#1493)

CMR-8064: Add support for bearer prefix in authorization header to mock-echo-app

--- mock-echo-app/src/cmr/mock_echo/api/tokens.clj
+++ mock-echo-app/src/cmr/mock_echo/api/tokens.clj
@@ -13,8 +13,7 @@
    [compojure.core :refer :all]))

 (def token-keys
-  #{
-    ;; Fields provided during login
+  #{;; Fields provided during login
     :username
     :client_id
     :password
@@ -34,12 +33,20 @@
     ;; Future enhancement: validate that min fields are provided
     (token-db/create context info)))

+(defn- strip-bearer-if-exists
+  "Remove 'Bearer ' from the front of the token if it exists"
+  [token]
+  (if (and (>= (count token) 7) (= "Bearer " (subs token 0 7)))
+    (subs token 7)
+    token))
+
 (defn- get-token-or-error
   "Helper for getting the token if it exists or thowing an error"
   [context token-id]
-  (if-let [token (token-db/fetch context token-id)]
-    token
-    (svc-errors/throw-service-error :unauthorized (str "Token [" token-id "] does not exist"))))
+  (let [token-id (strip-bearer-if-exists token-id)]
+    (if-let [token (token-db/fetch context token-id)]
+      token
+      (svc-errors/throw-service-error :unauthorized (str "Token [" token-id "] does not exist")))))

 (defn logout
   [context token-id]
@@ -90,29 +97,29 @@

 (defn build-routes [system]
   (routes
-    (context "/tokens" []
+   (context "/tokens" []
       ;; Login
-      (POST "/" {params :params context :request-context body :body}
-        (let [token (login context (slurp body))
-              url (str "http://localhost:3000/tokens/" (:id token))]
-          {:status 201
-           :content-type :json
-           :headers {"Location" url}
-           :body {:token token}}))
-      (POST "/get_token_info" {context :request-context headers :headers {token-id :id} :params}
-        (get-token-info context headers token-id))
-      (context "/:token-id" [token-id]
+     (POST "/" {params :params context :request-context body :body}
+       (let [token (login context (slurp body))
+             url (str "http://localhost:3000/tokens/" (:id token))]
+         {:status 201
+          :content-type :json
+          :headers {"Location" url}
+          :body {:token token}}))
+     (POST "/get_token_info" {context :request-context headers :headers {token-id :id} :params}
+       (get-token-info context headers token-id))
+     (context "/:token-id" [token-id]
         ;; Logout
-        (DELETE "/" {context :request-context}
-          (logout context token-id)
-          {:status 200})
-        (GET "/current_sids" {context :request-context}
+       (DELETE "/" {context :request-context}
+         (logout context token-id)
+         {:status 200})
+       (GET "/current_sids" {context :request-context}
           ;; Does not require sys admin token
-          (if (= "expired-token" token-id)
+         (if (= "expired-token" token-id)
             ;; echo-rest returns status code 400 for request with expired token
-            (ah/status-bad-request {:errors ["Token [expired-token] has expired."]})
-            (ah/status-ok (get-current-sids context token-id))))
-        (GET "/token_info" {context :request-context headers :headers}
-          (get-token-info context headers token-id))))
-    (GET "/availability" {context :request-context}
-      {:status 200})))
+           (ah/status-bad-request {:errors ["Token [expired-token] has expired."]})
+           (ah/status-ok (get-current-sids context token-id))))
+       (GET "/token_info" {context :request-context headers :headers}
+         (get-token-info context headers token-id))))
+   (GET "/availability" {context :request-context}
+     {:status 200})))


Add support for STAR

Add support for STAR

--- src/aerobio/htseq/common.clj
+++ src/aerobio/htseq/common.clj
@@ -270,10 +270,12 @@
                 :refs      (pams/get-params :refdir)
                 :index     (fs/join (pams/get-params :refdir) "Index")
                 :bt1index  (fs/join (pams/get-params :refdir) "BT1Index")
+                :starindex (fs/join (pams/get-params :refdir) "STARindex")
                 :samples   (fs/join base "Samples")
                 :collapsed (fs/join base "Samples/Collapsed")
                 :out       (fs/join base "Out")
                 :bams      (fs/join base "Out/Bams")
+                :star      (fs/join base "Out/STAR")
                 :fcnts     (fs/join base "Out/Fcnts")
                 :maps      (fs/join base "Out/Maps")
                 :fit       (fs/join base "Out/Fitness")
@@ -388,7 +390,7 @@
 (defn info-ks [] (-> @exp-info first second keys))

 (defn get-exp-info [eid & ks]
-  (let [otks #{:bams :fcnts :maps :fit :aggrs :charts}
+  (let [otks #{:bams :star :fcnts :maps :fit :aggrs :charts}
         rep? (coll/in :rep ks)
         ks (remove #{:rep} (filter identity ks)) ; remove any :rep or nil
         info (get-exp eid)
@@ -621,6 +623,8 @@
         bt (if (-> template (get-in [:nodes :ph1 :name])
                    (cljstr/includes? "bowtie1"))
              :bt1 :bt2)
+        star (-> template (get-in [:nodes :ph1 :name])
+                 (cljstr/includes? "star"))
         sample-names (get-exp-info eid :sample-names)
         sample-names (if repk
                        (mapcat #((get-exp-info eid :replicate-names) %)
@@ -632,7 +636,8 @@
              (fn[snm]
                (let [job (assoc-in phase1-job-template [:nodes :ph1 :args]
                                    (get-phase-1-args
-                                    exp eid snm :repk repk :bowtie bt))
+                                    exp eid snm :repk repk
+                                    :bowtie bt :star star))
                      cfg (-> job
                              (pg/config-pgm-graph-nodes get-toolinfo nil nil)
                              pg/config-pgm-graph)]
@@ -667,6 +672,11 @@
   get-comparison-files
   (fn[exptype & args] exptype))

+(defmulti
+  get-xcomparison-files
+  (fn[exptype & args] exptype))
+
+
 ;;;(ns-unmap 'aerobio.htseq.common 'run-phase-2)
 (defmulti
   ^{:doc "Each experiment type has its own phase 2 driver, and this
@@ -692,7 +702,7 @@
   (let [exp (get-exp-info eid :exp)]
     (cond
       (#{"phase-0" "phase-0b" "phase-0c" "phase-0d"
-         "phase-1" "bt2-phase-1" "bt1-phase-1"
+         "phase-1" "bt2-phase-1" "bt1-phase-1" "star-phase-1"
          "phase-2" "phase-2b"
          "phase-2-rnaseq" "phase-2-termseq"
          "phase-2-5NTap" "phase-2-5PTap"} action)
@@ -702,7 +712,7 @@
           (future
             (run-phase-0 eid recipient get-toolinfo template))

-          (#{"phase-1" "bt2-phase-1" "bt1-phase-1"} phase)
+          (#{"phase-1" "bt2-phase-1" "bt1-phase-1" "star-phase-1"} phase)
           (future
             (run-phase-1 eid recipient get-toolinfo template :repk rep))


woooo unspent txs

woooo unspent txs

--- src/bitsplit_cli/client.cljs
+++ src/bitsplit_cli/client.cljs
@@ -16,35 +16,53 @@
     (js/require "request")))

 (def urls
-  ["https://mainnet.helloblock.io/v1/addresses/$address$"
-   "https://blockchain.info/address/$address$?format=json"])
+  {:blockchain
+    "https://blockchain.info/unspent?address=$address$"
+   :helloblock
+    "https://mainnet.helloblock.io/v1/addresses/$address$/unspents"})

-(defn- balance [result]
-  (or (.-final_balance result) ; blockchain
-      (some-> result ; helloblock
-        (.-data)
-        (.-address)
-        (.-confirmedBalance))))
+(def standard-tx
+  {:blockchain
+    (fn [output]
+      {:tx-hash (.-tx_hash output)
+       :index (.-tx_index output)
+       :value (.-value output)})
+   :helloblock
+    (fn [output]
+      {:tx-hash (.-txHash output)
+       :index (.-index output)
+       :value (.-value output)})})

-(defn- parse-body [response]
-  (->> response
-    (second)
-    (.parse js/JSON)))
+(defn- response->txs [which result]
+  (if-let [array (or (.-unspent_outputs result) ; blockchain
+                     (some-> result ; helloblock
+                       (.-data)
+                       (.-unspents)))]
+    (map (which standard-tx) array)))

-(defn get-balance [urls address]
+(defn- parse-body [which response]
+  (try
+    (->> response
+      (second)
+      (.parse js/JSON)
+      (response->txs which))
+  (catch js/SyntaxError e)))
+
+(defn get-unspents [urls address]
   (go
-    (if-let [url (-> urls first (.replace "$address$" address))]
-      (let [response (<! (request url))]
+    (if-let [[which template] (first urls)]
+      (let [url (.replace template "$address$" address)
+            response (<! (request url))]
         (if-let [error (:error response)]
           (do
             (println "zomg error" error)
-            (<! (get-balance (rest urls) address)))
-          (-> response parse-body balance))))))
+            (<! (get-unspents (rest urls) address)))
+          (parse-body which response))))))

-(defn address->balance [urls address]
+(defn address->unspents [urls address]
   (go
-    (let [amount (<! (get-balance urls address))]
-      [address amount])))
+    (let [unspents (<! (get-unspents urls address))]
+      [address unspents])))

 (defn- send? [fee amount]
     (< (* 3 fee) amount))
@@ -60,12 +78,14 @@
         (-> wallet .-addresses js->clj))
     (unspent-amounts [this]
       (let [my-addrs (addresses this)]
+        (println "our addresses" my-addrs)
         (if (empty? my-addrs)
           (go nil)
           (->> my-addrs
-            (map (partial address->balance urls))
+            (map (partial address->unspents urls))
             (a/merge)
-            (a/into { })))))
+            (a/into { })
+            (a/map< (fn[x] (println "sup got some txs" x) x))))))
     (unspent-channel [this]
       (let [return (a/chan)]
         (js/setInterval


audit link GET fixed

audit link GET fixed

--- src/celestial/api/audits.clj
+++ src/celestial/api/audits.clj
@@ -13,6 +13,7 @@
   "Auditing api"
   (:refer-clojure :exclude  [name type])
   (:require
+    [clojure.data.json :as json]
     [celestial.persistency.audits :as a]
     [celestial.common :refer (import-logging success wrap-errors conflict bad-req link)]
     [swag.model :refer (defmodel defc)]
@@ -32,10 +33,9 @@
   (GET- "/audits/:name" [^:string name] {:nickname "getAudit" :summary "Get audit by name"}
         (success (a/get-audit name)))

-  (GET- "/audits/link" [^:link-input in] {:nickname "linkFor" :summary "Get audit link"}
-     (let [{:keys [name args]} in {:keys [query]} (a/get-audit name)]
-          (success (link query args))
-          )))
+  (GET- "/audits/:name/:args" [^:string name ^:string args] {:nickname "linkFor" :summary "Get audit link"}
+    (let [{:keys [query]} (a/get-audit name)]
+       (success {:link (link query (json/read-str args :key-fn keyword))}))))

 (defroutes- audits {:path "/audit" :description "Operations on audits"}
   (POST- "/audits" [& ^:audit audit] {:nickname "addAudit" :summary "Add audit"}


Convert assert in binary_search example into a pre-condition

--- binary-search/example.clj
+++ binary-search/example.clj
@@ -5,7 +5,7 @@

 (defn search-for
   [elem alist]
-  (assert (apply <= alist) "Input list must be sorted")
+  {:pre [(apply <= alist)]}
   (let [middle (middle alist)
         cur-elem (nth alist middle)]
     (cond


Response body tekstinä

Response body tekstinä

--- mtg-pairings-wer/src/mtg_pairings/uploader.clj
+++ mtg-pairings-wer/src/mtg_pairings/uploader.clj
@@ -20,10 +20,12 @@
 (defn options [api-key body]
   {:timeout 1000
    :query-params {:key api-key}
-   :body (json/generate-string body)})
+   :body (json/generate-string body)
+   :headers {"Content-Type" "application/json"}
+   :as :text})

 (defn upload-tournament! [url api-key tournament & [callback]]
-  (POST (str url "/tournament")
+  (POST (str url "/tournament/")
         (options api-key tournament)
         callback))


clean up config docs

clean up config docs

--- sidecar/src/figwheel_sidecar/schemas/config.clj
+++ sidecar/src/figwheel_sidecar/schemas/config.clj
@@ -487,7 +487,7 @@

 Compile Paths - The :source-paths vector of paths is passed to the
 compiler and tells it to compile these directories.  The ClojureScript
-compiler then interates through the CLJS sources in these directories
+compiler then iterates through the CLJS sources in these directories
 and compiles them. You can override :source-paths and specify which
 paths are sent to the compiler with :compile-paths.

@@ -504,15 +504,12 @@

 The default value is the contents of :source-paths

-These paths should be relative from the root of the project to the
-root the namespace.  For example, if you have an src/example/core.cljs
-file that contains a example.core namespace, the source path to this
-file is \"src\"
+These paths should be relative from the root of the project.

   :watch-paths [\"src\"]")

 (def-key ::compile-paths (s/every non-blank-string? :into [] :kind sequential?)
-  "A vector of paths to the directories of source files that you want compiled.
+  "A vector of paths to the directories of cljs source files that you want compiled.

 The default value is the contents of :source-paths


Add support for gzipped nnml files

Add support for gzipped nnml files

--- src/net/dishevelled/mailindex/backends/nnml.clj
+++ src/net/dishevelled/mailindex/backends/nnml.clj
@@ -2,23 +2,36 @@
   (:require [clojure.java.io :refer [file reader]]
             [net.dishevelled.mailindex :refer [debug]]
             [clojure.set])
-  (:import (java.io FileInputStream IOException)
-           (java.util Date)))
-
+  (:import (java.io InputStream FileInputStream ByteArrayOutputStream IOException)
+           (java.util Date)
+           (java.util.zip GZIPInputStream)))

 (defn- mtime-to-days [mtime]
   (let [now (.getTime (Date.))]
     (int (/ (- now mtime) 1000 60 60 24))))

+(defn input-stream-for-file [file]
+  (let [fis (FileInputStream. file)]
+    (if (.endsWith (.getName file) ".gz")
+      (GZIPInputStream. fis)
+      fis)))
+
 (defn- message-bytes
   "Return the bytes of a message."
   [^String msg]
   (try
-    (let [out (byte-array (.length (file msg)))]
-      (with-open [fis (FileInputStream. msg)]
-        (.read fis out))
-      out)
+    (let [f (file msg)
+          buf (byte-array 4096)
+          out (ByteArrayOutputStream. (.length f))]
+      ;; Our initial length is really just a guess here.  We'll be right for
+      ;; uncompressed files and wrong for everything else :)
+      (with-open [^InputStream is (input-stream-for-file f)]
+        (loop [len (.read is buf)]
+          (when (>= len 0)
+            (.write out buf 0 len)
+            (recur (.read is buf)))))
+      (.toByteArray out))
     (catch IOException _
       (byte-array 0))))

@@ -28,7 +41,7 @@
   [base filename]
   (let [[whole group num]
         (first
-         (re-seq (re-pattern (str base "/*" "(.*?)" "/" "([0-9]+)$"))
+         (re-seq (re-pattern (str base "/*" "(.*?)" "/" "([0-9]+)(:?\\.gz)?$"))
                  filename))]
     {:group (.replace group "/" ".") :num num}))

@@ -53,7 +66,8 @@
            base
            (System/getProperty "user.dir"))
     (filter #(let [path (id-to-filename base %)
-                   path-exists? (.exists (java.io.File. path))]
+                   path-exists? (or (.exists (java.io.File. path))
+                                    (.exists (java.io.File. (str path ".gz"))))]
                (debug "Does '%s' exist?  %s" path path-exists?)
                (not path-exists?))
             ids)))
@@ -68,7 +82,7 @@
               (concat cmd ["-mtime" (str "-" (inc
                                               (mtime-to-days index-mtime)))])
               cmd)
-        messages (set (filter #(re-find #"/[0-9]+$" %)
+        messages (set (filter #(re-find #"/[0-9]+(\.gz)?$" %)
                               (line-seq (reader (.. Runtime
                                                     getRuntime
                                                     (exec (into-array cmd))


do less work when build data updates

do less work when build data updates

--- frontend/components/build.cljs
+++ frontend/components/build.cljs
@@ -66,6 +66,19 @@
   ;; XXX Displays nothing for now
   "")

+(defn container-pill [{:keys [container current-container-id]} owner opts]
+  (reify
+    om/IRender
+    (render [_]
+      (html
+       (let [container-id (container-model/id container)
+             controls-ch (get-in opts [:comms :controls])]
+         [:li {:class (when (= container-id current-container-id) "active")}
+          [:a.container-selector
+           {:on-click #(put! controls-ch [:container-selected container-id])
+            :class (container-model/status-classes container)}
+           (str "C" (:index container))]])))))
+
 (defn container-pills [container-data owner opts]
   (reify
     om/IRender
@@ -73,16 +86,36 @@
       (let [{:keys [containers current-container-id]} container-data
             controls-ch (get-in opts [:comms :controls])]
         (html
-         [:div.containers.pagination.pagination-centered
-          {:data-bind "sticky_waypoint: {offset: 0}"}
+         [:div.containers.pagination.pagination-centered (when-not (< 1 (count containers))
+                                                           {:style {:display "none"}})
           [:ul.container-list
-           (for [container containers
-                 :let [container-id (container-model/id container)]]
-             [:li {:class (when (= container-id current-container-id) "active")}
-              [:a.container-selector
-               {:on-click #(put! controls-ch [:container-selected container-id])
-                :class (container-model/status-classes container)}
-               (str "C" (:index container))]])]])))))
+           (for [container containers]
+             (om/build container-pill
+                       {:container container
+                        :current-container-id current-container-id}
+                       {:opts opts
+                        :react-key (:index container)}))]])))))
+
+(defn notices [build-data owner opts]
+  (reify
+    om/IRender
+    (render [_]
+      (html
+       (let [build (:build build-data)
+             controls-ch (get-in opts [:comms :controls])]
+         [:div.row-fluid
+          [:div.offset1.span10
+           [:div (common/messages (:messages build))]
+           [:div (report-error build controls-ch)]
+           [:div {:data-bind "if: $root.project() && $root.project().show_build_page_trial_notice"}
+            (project-trial-notice)]
+           [:div {:data-bind "if: $root.project() && $root.project().show_enable_project_notice"}
+            (project-enable-notice)]
+           [:div.row-fluid
+            {:data-bind "if: $root.show_follow_project_button"}
+            (project-follow-button)]
+           (when (build-model/display-build-invite build)
+             (build-invite build))]])))))

 (defn build [data owner opts]
   (reify
@@ -95,29 +128,15 @@
         (html
          [:div#build-log-container
           (if-not build
-            [:div
+           [:div
              (common/flashes)
              [:div.loading-spinner common/spinner]]

             [:div
              (om/build build-head/build-head (dissoc build-data :container-data) {:opts opts})
              (common/flashes)
-             [:div.row-fluid
-              [:div.offset1.span10
-               [:div (common/messages (:messages build))]
-               [:div (report-error build controls-ch)]
-               [:div {:data-bind "if: $root.project() && $root.project().show_build_page_trial_notice"}
-                (project-trial-notice)]
-               [:div {:data-bind "if: $root.project() && $root.project().show_enable_project_notice"}
-                (project-enable-notice)]
-               [:div.row-fluid
-                {:data-bind "if: $root.show_follow_project_button"}
-                (project-follow-button)]
-               (when (build-model/display-build-invite build)
-                 (build-invite build))]]
-
-             (when (< 1 (count (:containers container-data)))
-               (om/build container-pills container-data {:opts opts}))
+             (om/build notices (dissoc build-data :container-data {:opts opts}))
+             (om/build container-pills container-data {:opts opts})
              (om/build build-steps/container-build-steps container-data {:opts opts})

              (when (< 1 (count (:steps build)))


Delegate should have a protocol now

Delegate should have a protocol now

--- src-cljs/frontend/utils/github.cljs
+++ src-cljs/frontend/utils/github.cljs
@@ -28,7 +28,7 @@
                                                         (str js/window.location.pathname
                                                              js/window.location.hash))}
                                           (when (not= auth-host js/window.location.host)
-                                            {"delegate" js/window.location.host})))
+                                            {"delegate" (str auth-protocol "://" js/window.location.host)})))
                      (assoc :protocol (or (aget js/window "renderContext" "auth_protocol")
                                           "https"))
                      str)]


search canonical to include "the"

search canonical to include "the"

--- src/clj/apollo/db/schema.clj
+++ src/clj/apollo/db/schema.clj
@@ -65,7 +65,7 @@

 (defn create-tbl! [db, tbl]
-  (let [args (cons (:name tbl) (:columns tbl))]
+    (let [args (cons (:name tbl) (:columns tbl))]
     (sql/db-do-commands db
                       (apply sql/create-table-ddl args))))

@@ -166,7 +166,7 @@
         (let [db-results (-> (artist-list) (k/where {:id [< "a"]})(k/select)) ;; needs fix for canonical
               results (filter (fn [x] (not (= (:id x) ""))) db-results)]
           (take-while (fn [x] (not (= (subs (str (:id x)) 0 1) "a"))) results))
-        :else (-> (artist-list) (k/where {:name [like (format "%s%%" prefix)]}) (k/select))))
+        :else (-> (artist-list) (k/where {:id [like (format "%s%%" prefix)]}) (k/select))))

 (defn album-list-by-artist [artist]
   (-> (k/select* album) (k/where {:artist_id (utils/canonicalize artist)}) (k/order :year) (k/select)))


Return payload on insert / update, add find-by-id

--- src/clj/clojuredocs/data.clj
+++ src/clj/clojuredocs/data.clj
@@ -10,16 +10,21 @@
   (let [context-name :create
         coll (:mongo-coll comp)]
     (validate-payload comp context-name payload)
-    (mon/insert! coll payload)))
+    (mon/insert! coll payload)
+    payload))

 (defn update-where! [comp where-fn payload]
   (let [context-name :update
         coll (:mongo-coll comp)]
     (validate-payload comp context-name payload)
-    (mon/update! coll (where-fn payload) payload)))
+    (mon/update! coll (where-fn payload) payload)
+    payload))

 (defn update-by-id! [schema payload]
   (update-where! schema #(select-keys % [:_id]) payload))
+
+(defn find-by-id [{:keys [mongo-coll]} _id]
+  (mon/fetch-one mongo-coll :where {:_id _id}))

 ;; Examples
@@ -39,7 +44,6 @@
             :var.ns ns
             :var.library-url library-url}
     :sort {:created-at 1}))
-

 ;; Notes


Optimized indent-string with ^long.

Optimized indent-string with ^long.

--- src/clj/clongra/core/str.clj
+++ src/clj/clongra/core/str.clj
@@ -101,9 +101,9 @@
 (defn ^String indent-string
   "Generates an indentation string of n indent-with elements
   (space character by default)."
-  ([n] (indent-string n \space))
-
-  ([n indent-with]
+  ([^long n] (indent-string n \space))
+
+  ([^long n indent-with]
      (let [sb (new StringBuilder)]
        (dotimes [i n] (. sb (append indent-with)))
        (str sb))))


fix a bug - forgot to refresh the points ns

--- src/clj/ephemeris/points.clj
+++ src/clj/ephemeris/points.clj
@@ -27,7 +27,7 @@

 (defn known? [kwd]
   (if (keyword? kwd)
-    (contains? dat kwd)
+    (contains? (deref dat) kwd)
     false))

 (defn lookup [what]


Clarify Chaikin step algorithm

Clarify Chaikin step algorithm

--- src/clj/genartlib/curves.clj
+++ src/clj/genartlib/curves.clj
@@ -2,17 +2,15 @@
   (:use [genartlib.algebra :only [interpolate]]))

 (defn- single-chaikin-step [points tightness]
-  (loop [points points
-         new-points [(first points)]]
-    (if (<= (count points) 1)
-      (vec (concat new-points [(last points)]))
-      (let [[start-x start-y] (first points)
-            [end-x end-y] (second points)
-            q-x (interpolate start-x end-x (+ 0.0 tightness))
-            q-y (interpolate start-y end-y (+ 0.0 tightness))
-            r-x (interpolate start-x end-x (- 1.0 tightness))
-            r-y (interpolate start-y end-y (- 1.0 tightness))]
-        (recur (rest points) (concat new-points [[q-x q-y] [r-x r-y]]))))))
+  (concat [(first points)]
+          (mapcat (fn [[[start-x start-y] [end-x end-y]]]
+                    (let [q-x (interpolate start-x end-x (+ 0.0 tightness))
+                          q-y (interpolate start-y end-y (+ 0.0 tightness))
+                          r-x (interpolate start-x end-x (- 1.0 tightness))
+                          r-y (interpolate start-y end-y (- 1.0 tightness))]
+                      [[q-x q-y] [r-x r-y]]))
+                  (partition 2 1 points))
+          [(last points)]))

 (defn chaikin-curve


Fix image being shown in popup

Fix image being shown in popup

--- src/cljs/decktouch/core.cljs
+++ src/cljs/decktouch/core.cljs
@@ -12,15 +12,18 @@
 ;; -------------------------
 ;; Views

+(defn img [url]
+  (str "<img src='" url "'>"))
+
 (defn card-in-list [card card-id]
   (let [image-name (clojure.string/replace (get card "imageName") #" " "_")
-        image-link (str "http://mtgimage.com/multiverseid/" image-name ".jpg")]
+        image-link (str "http://mtgimage.com/card/" image-name ".jpg")]
   [:li
     [:a {:id card-id
          :data-toggle "tooltip"
          :data-placement "bottom"
          :data-html true
-         :title [:img {:src image-link}]}
+         :title (img image-link)}
          (str (get card "name"))]]))

 (defn card-in-list-did-mount [card-id]


Cleanup names.

Cleanup names.

--- src/cljs/primes/numbers.cljs
+++ src/cljs/primes/numbers.cljs
@@ -95,13 +95,13 @@
   (let [by-prime (group-results identity (factors n))]
     (sort > (map second by-prime))))

-(defn signature-and-value [n]
+(defn signature-and-value-nocache [n]
   [(signature n) n])

-(def signature-and-value-m (memoize signature-and-value))
+(def signature-and-value (memoize signature-and-value-nocache))

 (defn signatures [thru-n]
-  (map signature-and-value-m (range 2 thru-n)))
+  (map signature-and-value (range 2 thru-n)))

 (defn sort-groups
   "Sort groups based on distance from origin in 'primes space'"


Misspelled word edit.

Misspelled word edit.

--- src/cljs/quiz/questions.cljs
+++ src/cljs/quiz/questions.cljs
@@ -42,21 +42,21 @@

    {:question "What does Hitchhiker's Guide to the Galaxy has to say about planet Earth?"

-    :choices ["Deadly"
-              "Beautiful"
-              "Boring"
-              "Harmless"]
+    :choices ["Deadly."
+              "Beautiful."
+              "Boring."
+              "Harmless."]
     :answer "Harmless"}

    {:question "... and after Ford Prefect spending 15 years stuck on the planet, what does it expand to?"
-    :choices ["Deadly but boring"
-              "Beautiful...kind of"
-              "Boring but deadly"
-              "Mostly harmless"]
+    :choices ["Deadly but boring."
+              "Beautiful...kind of."
+              "Boring but deadly."
+              "Mostly harmless."]
     :answer "Mostly harmless"
     }

-   {:question "Arthur Dent, when trying to get Heart of Gold's supercomputer to brew him a drink, was invariably getting a cup of hot, brown liquied, which was almost, but not quite, entirely unlike... what?"
+   {:question "Arthur Dent, when trying to get Heart of Gold's supercomputer to brew him a drink, was invariably getting a cup of hot, brown liquid, which was almost, but not quite, entirely unlike... what?"
     :choices [ "Tea"
                "Coffee"
                "Gin"


simplify ai code

simplify ai code

--- src/cljs/triboard/ai/ai.cljs
+++ src/cljs/triboard/ai/ai.cljs
@@ -44,11 +44,10 @@
         move-diff (get (score-move ai transition) (:player ai))
         new-moves (:transitions (game/current-state new-game))
         next-diff (worst-possible-score-from ai new-moves)]
-    (+ move-diff next-diff)))
+    {:scoring (+ move-diff next-diff)
+     :game new-game}))

-(defn- max-by
-  [key-fn coll]
-  (apply max-key (memoize key-fn) coll))
+(defn- max-by [key-fn coll] (apply max-key key-fn coll))

 ;; -----------------------------------------
@@ -59,18 +58,16 @@
   :args (s/tuple ::game/game ::player/player)
   :ret ::game/game)

-(defn- best-move                                    ;; TODO - Compute games directly...
-  [game]
-  (let [turn (game/current-state game)
-        ai (make-ai (:board turn) (:player turn))]
-    (first
-      (max-by #(move-best-outcome ai game %)
-        (turn/player-transitions turn))        ;; TODO - To compute game directly, need of a transition between games
-      )))
-
-(defn play-best-move
+(defn- play-best-move
   "[SIMPLISTIC] Play the best move for a player based on:
    * The immediate gain
    * The worse immediate lost afterwards"
   [game]
-  (game/play-move game (best-move game)))
+  (let [turn (game/current-state game)
+        ai (make-ai (:board turn) (:player turn))]
+    (:game
+      (max-by :scoring
+        (map
+          #(move-best-outcome ai game %)
+          (turn/player-transitions turn)))
+      )))


Fix problems with within-with-context? preconditions

--- src/clojure/neko/context.clj
+++ src/clojure/neko/context.clj
@@ -25,8 +25,8 @@
   (instance? Context x))

 (defn- within-with-context?
-  "Determines whether the argument is an instance of Context."
-  [x]
+  "Ensures that the function is within a valid with-context form."
+  []
   (and (bound? #'*context*)
        (context? *context*)))

@@ -126,7 +126,7 @@
     :post [(integer? %)]}
    (resolve-it name context type))
   ([type name]
-   {:pre  [within-with-context?
+   {:pre  [(within-with-context?)
            (keyword? type)
            (resolvable? name)]
     :post [(integer? %)]}
@@ -143,14 +143,14 @@
   If within a with-context form, the context parameter may be omitted."
   {:arglists '([context? id-or-name & args])}
   ([id-or-name]
-   {:pre  [within-with-context?
+   {:pre  [(within-with-context?)
            (resolvable? id-or-name)]
     :post [(string? %)]}
    (get-string *context* id-or-name))
   ([context id-or-name]
    {:pre  [(or (and (context? context)
                     (resolvable? id-or-name))
-               (and within-with-context?
+               (and (within-with-context?)
                     (resolvable? context)))]
     :post [(string? %)]}
    (if (instance? Context context)
@@ -159,7 +159,7 @@
   ([context id-or-name & args]
    {:pre  [(or (and (context? context)
                     (resolvable? id-or-name))
-               (and within-with-context?
+               (and (within-with-context?)
                     (resolvable? context)))]
     :post [(string? %)]}
    (if (instance? Context context)
@@ -172,7 +172,7 @@
   "Finds the resource ID for the layout with the given name.  This is simply a
   convenient way of calling (resolve-resource context :layout name)."
   ([name]
-   {:pre  [within-with-context?
+   {:pre  [(within-with-context?)
            (resolvable? name)]
     :post [(integer? %)]}
    (resolve-layout name *context*))
@@ -188,7 +188,7 @@
   :layout-inflater for the layout inflater service.  If within a with-context
   form, the context may be omitted."
   ([type]
-   {:pre [within-with-context?]}
+   {:pre [(within-with-context?)]}
    (get-system-service *context* type))
   ([^Context context type]
    {:pre [(keyword? type)
@@ -205,7 +205,7 @@
   be an integer ID or a keyword name for the desired layout.  If within a
   with-context form, the context may be omitted."
   ([id-or-name]
-   {:pre  [within-with-context?
+   {:pre  [(within-with-context?)
            (resolvable? id-or-name)]
     :post [(instance? android.view.View %)]}
    (get-layout *context* id-or-name))


Added masking for flipped cards

Added masking for flipped cards

--- src/codenames/gamelayout.clj
+++ src/codenames/gamelayout.clj
@@ -3,20 +3,22 @@
             [clojure.string :as strings]))

 (defn spymaster-view-columns [game-state]
-  (let [bystanders (map :name (:bystanders @game-state))
-        reds (map :name (:red-agents @game-state))
-        blues (map :name (:blue-agents @game-state))
-        assassin (map :name (:assassin @game-state))
-        agents (map :name (:agents @game-state))
+  (let [bystanders (:bystanders @game-state)
+        reds (:red-agents @game-state)
+        blues (:blue-agents @game-state)
+        assassin (:assassin @game-state)
+        agents (:agents @game-state)
         start-elem (fn [bg-clr txt-clr] (str ""))]
-           (for [agent agents]
-             (if (some #{agent} bystanders)
-               (str (start-elem "grey" "black") agent "	")
-               (if (some #{agent} assassin)
-                 (str (start-elem "black" "white") agent "	")
-                 (if (some #{agent} reds)
-                   (str (start-elem "red" "white") agent "	")
-                   (str (start-elem "blue" "white") agent "	")))))))
+    (for [agent agents]
+      (let [agt-nm (:name agent)
+            agt-dsply (if (:flipped? agent) "**********" agt-nm)]
+        (if (some #{agt-nm} (map :name bystanders))
+          (str (start-elem "grey" "black") agt-dsply "	")
+               (if (some #{agt-nm} (map :name assassin))
+                 (str (start-elem "black" "white") agt-dsply "	")
+                 (if (some #{agt-nm} (map :name reds))
+                   (str (start-elem "red" "white") agt-dsply "	")
+                   (str (start-elem "blue" "white") agt-dsply "	"))))))))

 (defn spymaster-view [game-state num-cols]
   (let [columns (codenames.gamelayout/spymaster-view-columns game-state)]
@@ -28,6 +30,7 @@
       (str "
" (apply str (addrows columns)) "
"))))

-
-(def game-state (game/new-game))
-(spymaster-view game-state 5)
+(comment
+  (def game-state (game/new-game))
+  (spymaster-view game-state 5)
+)


don't repeat tense information: use babel.espanol.grammar/tenses

--- src/babel/espanol/writer.clj
+++ src/babel/espanol/writer.clj
@@ -235,13 +235,5 @@
                                                         {:comp {:synsem {:agr {:person :3rd
                                                                                :number :sing}
                                                                          :pronoun false}}}))))
-                                (list {:synsem {:sem {:tense :conditional}}}
-                                      {:synsem {:sem {:tense :future}}}
-                                      {:synsem {:sem {:tense :present}}}
-                                      {:synsem {:sem {:aspect :progressive
-                                                      :tense :past}}}
-                                      {:synsem {:sem {:aspect :perfect
-                                                      :tense :past}}}
-
-                                      ))
-                        )))))))))
+                                (vals babel.espanol.grammar/tenses)))))))))))
+


Validate emojis before img-ing them

Validate emojis before img-ing them

--- src/cljs/openslack/text.cljs
+++ src/cljs/openslack/text.cljs
@@ -16,20 +16,6 @@
   [regex match-converter]
   (swap! enrichers conj (make-enricher regex match-converter)))

-(def img-regex #"https?://.*\.(?:jpe?g|gif|png)")
-(def img-converter (fn [e]
-                     [:img {:src e
-                            :class-name "message-image"}]))
-(register-enricher! img-regex img-converter)
-
-(def emoji-regex #"\:[^\\s:]+\:")
-(def emoji-converter (fn [e]
-                       [:img {:src (str "/static/imgs/emoji/"
-                                        (.substring e 1 (dec (.-length e)))
-                                        ".png")
-                              :class-name "emoji"}]))
-(register-enricher! emoji-regex emoji-converter)
-
 (defn enrich-text
   [s]
   (let [result (atom [s])]
@@ -39,3 +25,906 @@
                                  (f v)
                                  [v])) %)))
     (filter (complement empty?) @result)))
+
+;; Images
+
+(def img-regex #"https?://.*\.(?:jpe?g|gif|png)")
+(def img-converter (fn [e]
+                     [:img {:src e
+                            :class-name "message-image"}]))
+(register-enricher! img-regex img-converter)
+
+;; Emoji
+
+(def valid-emojis
+  #{"100"
+    "1234"
+    "-1"
+    "+1"
+    "8ball"
+    "abcd"
+    "abc"
+    "ab"
+    "accept"
+    "aerial_tramway"
+    "airplane"
+    "alarm_clock"
+    "alien"
+    "ambulance"
+    "anchor"
+    "angel"
+    "anger"
+    "angry"
+    "anguished"
+    "ant"
+    "a"
+    "apple"
+    "aquarius"
+    "aries"
+    "arrow_backward"
+    "arrow_double_down"
+    "arrow_double_up"
+    "arrow_down"
+    "arrow_down_small"
+    "arrow_forward"
+    "arrow_heading_down"
+    "arrow_heading_up"
+    "arrow_left"
+    "arrow_lower_left"
+    "arrow_lower_right"
+    "arrow_right_hook"
+    "arrow_right"
+    "arrows_clockwise"
+    "arrows_counterclockwise"
+    "arrow_up_down"
+    "arrow_upper_left"
+    "arrow_upper_right"
+    "arrow_up"
+    "arrow_up_small"
+    "articulated_lorry"
+    "art"
+    "astonished"
+    "atm"
+    "baby_bottle"
+    "baby_chick"
+    "baby"
+    "baby_symbol"
+    "back"
+    "baggage_claim"
+    "balloon"
+    "ballot_box_with_check"
+    "bamboo"
+    "banana"
+    "bangbang"
+    "bank"
+    "barber"
+    "bar_chart"
+    "baseball"
+    "basketball"
+    "bath"
+    "bathtub"
+    "battery"
+    "bear"
+    "bee"
+    "beer"
+    "beers"
+    "beetle"
+    "beginner"
+    "bell"
+    "bento"
+    "bicyclist"
+    "bike"
+    "bikini"
+    "bird"
+    "birthday"
+    "black_circle"
+    "black_joker"
+    "black_medium_small_square"
+    "black_medium_square"
+    "black_nib"
+    "black_small_square"
+    "black_square_button"
+    "black_square"
+    "blossom"
+    "blowfish"
+    "blue_book"
+    "blue_car"
+    "blue_heart"
+    "blush"
+    "boar"
+    "boat"
+    "bomb"
+    "bookmark"
+    "bookmark_tabs"
+    "book"
+    "books"
+    "boom"
+    "boot"
+    "bouquet"
+    "bowling"
+    "bow"
+    "bowtie"
+    "boy"
+    "b"
+    "bread"
+    "bride_with_veil"
+    "bridge_at_night"
+    "briefcase"
+    "broken_heart"
+    "bug"
+    "bulb"
+    "bullettrain_front"
+    "bullettrain_side"
+    "bus"
+    "busstop"
+    "bust_in_silhouette"
+    "busts_in_silhouette"
+    "cactus"
+    "cake"
+    "calendar"
+    "calling"
+    "camel"
+    "camera"
+    "cancer"
+    "candy"
+    "capital_abcd"
+    "capricorn"
+    "card_index"
+    "carousel_horse"
+    "car"
+    "cat2"
+    "cat"
+    "cd"
+    "chart"
+    "chart_with_downwards_trend"
+    "chart_with_upwards_trend"
+    "checkered_flag"
+    "cherries"
+    "cherry_blossom"
+    "chestnut"
+    "chicken"
+    "children_crossing"
+    "chocolate_bar"
+    "christmas_tree"
+    "church"
+    "cinema"
+    "circus_tent"
+    "city_sunrise"
+    "city_sunset"
+    "clapper"
+    "clap"
+    "clipboard"
+    "clock1030"
+    "clock10"
+    "clock1130"
+    "clock11"
+    "clock1230"
+    "clock12"
+    "clock130"
+    "clock1"
+    "clock230"
+    "clock2"
+    "clock330"
+    "clock3"
+    "clock430"
+    "clock4"
+    "clock530"
+    "clock5"
+    "clock630"
+    "clock6"
+    "clock730"
+    "clock7"
+    "clock830"
+    "clock8"
+    "clock930"
+    "clock9"
+    "closed_book"
+    "closed_lock_with_key"
+    "closed_umbrella"
+    "cloud"
+    "cl"
+    "clubs"
+    "cn"
+    "cocktail"
+    "coffee"
+    "cold_sweat"
+    "collision"
+    "computer"
+    "confetti_ball"
+    "confounded"
+    "confused"
+    "congratulations"
+    "construction"
+    "construction_worker"
+    "convenience_store"
+    "cookie"
+    "cool"
+    "cop"
+    "copyright"
+    "corn"
+    "couplekiss"
+    "couple"
+    "couple_with_heart"
+    "cow2"
+    "cow"
+    "credit_card"
+    "crocodile"
+    "crossed_flags"
+    "crown"
+    "crying_cat_face"
+    "cry"
+    "crystal_ball"
+    "cupid"
+    "curly_loop"
+    "currency_exchange"
+    "curry"
+    "custard"
+    "customs"
+    "cyclone"
+    "dancer"
+    "dancers"
+    "dango"
+    "dart"
+    "dash"
+    "date"
+    "deciduous_tree"
+    "department_store"
+    "de"
+    "diamond_shape_with_a_dot_inside"
+    "diamonds"
+    "disappointed"
+    "disappointed_relieved"
+    "dizzy_face"
+    "dizzy"
+    "dog2"
+    "dog"
+    "dollar"
+    "dolls"
+    "dolphin"
+    "do_not_litter"
+    "donut"
+    "door"
+    "doughnut"
+    "dragon_face"
+    "dragon"
+    "dress"
+    "dromedary_camel"
+    "droplet"
+    "dvd"
+    "ear_of_rice"
+    "ear"
+    "earth_africa"
+    "earth_americas"
+    "earth_asia"
+    "eggplant"
+    "egg"
+    "eight"
+    "eight_pointed_black_star"
+    "eight_spoked_asterisk"
+    "electric_plug"
+    "elephant"
+    "e-mail"
+    "email"
+    "end"
+    "envelope"
+    "es"
+    "european_castle"
+    "european_post_office"
+    "euro"
+    "evergreen_tree"
+    "exclamation"
+    "expressionless"
+    "eyeglasses"
+    "eyes"
+    "facepunch"
+    "factory"
+    "fallen_leaf"
+    "family"
+    "fast_forward"
+    "fax"
+    "fearful"
+    "feelsgood"
+    "feet"
+    "ferris_wheel"
+    "file_folder"
+    "finnadie"
+    "fire_engine"
+    "fire"
+    "fireworks"
+    "first_quarter_moon"
+    "first_quarter_moon_with_face"
+    "fish_cake"
+    "fishing_pole_and_fish"
+    "fish"
+    "fist"
+    "five"
+    "flags"
+    "flashlight"
+    "floppy_disk"
+    "flower_playing_cards"
+    "flushed"
+    "foggy"
+    "football"
+    "fork_and_knife"
+    "fountain"
+    "four_leaf_clover"
+    "four"
+    "free"
+    "fried_shrimp"
+    "fries"
+    "frog"
+    "frowning"
+    "fr"
+    "fuelpump"
+    "full_moon"
+    "full_moon_with_face"
+    "fu"
+    "game_die"
+    "gb"
+    "gemini"
+    "gem"
+    "ghost"
+    "gift_heart"
+    "gift"
+    "girl"
+    "globe_with_meridians"
+    "goat"
+    "goberserk"
+    "godmode"
+    "golf"
+    "grapes"
+    "green_apple"
+    "green_book"
+    "green_heart"
+    "grey_exclamation"
+    "grey_question"
+    "grimacing"
+    "grinning"
+    "grin"
+    "guardsman"
+    "guitar"
+    "gun"
+    "haircut"
+    "hamburger"
+    "hammer"
+    "hamster"
+    "handbag"
+    "hand"
+    "hankey"
+    "hash"
+    "hatched_chick"
+    "hatching_chick"
+    "headphones"
+    "hear_no_evil"
+    "heartbeat"
+    "heart_decoration"
+    "heart_eyes_cat"
+    "heart_eyes"
+    "heart"
+    "heartpulse"
+    "hearts"
+    "heavy_check_mark"
+    "heavy_division_sign"
+    "heavy_dollar_sign"
+    "heavy_exclamation_mark"
+    "heavy_minus_sign"
+    "heavy_multiplication_x"
+    "heavy_plus_sign"
+    "helicopter"
+    "herb"
+    "hibiscus"
+    "high_brightness"
+    "high_heel"
+    "hocho"
+    "honeybee"
+    "honey_pot"
+    "horse"
+    "horse_racing"
+    "hospital"
+    "hotel"
+    "hotsprings"
+    "hourglass_flowing_sand"
+    "hourglass"
+    "house"
+    "house_with_garden"
+    "hurtrealbad"
+    "hushed"
+    "ice_cream"
+    "icecream"
+    "ideograph_advantage"
+    "id"
+    "imp"
+    "inbox_tray"
+    "incoming_envelope"
+    "information_desk_person"
+    "information_source"
+    "innocent"
+    "interrobang"
+    "iphone"
+    "it"
+    "izakaya_lantern"
+    "jack_o_lantern"
+    "japanese_castle"
+    "japanese_goblin"
+    "japanese_ogre"
+    "japan"
+    "jeans"
+    "joy_cat"
+    "joy"
+    "jp"
+    "keycap_ten"
+    "key"
+    "kimono"
+    "kissing_cat"
+    "kissing_closed_eyes"
+    "kissing_face"
+    "kissing_heart"
+    "kissing"
+    "kissing_smiling_eyes"
+    "kiss"
+    "koala"
+    "koko"
+    "kr"
+    "large_blue_circle"
+    "large_blue_diamond"
+    "large_orange_diamond"
+    "last_quarter_moon"
+    "last_quarter_moon_with_face"
+    "laughing"
+    "leaves"
+    "ledger"
+    "left_luggage"
+    "left_right_arrow"
+    "leftwards_arrow_with_hook"
+    "lemon"
+    "leopard"
+    "leo"
+    "libra"
+    "light_rail"
+    "link"
+    "lips"
+    "lipstick"
+    "lock"
+    "lock_with_ink_pen"
+    "lollipop"
+    "loop"
+    "loudspeaker"
+    "love_hotel"
+    "love_letter"
+    "low_brightness"
+    "mag"
+    "mag_right"
+    "mahjong"
+    "mailbox_closed"
+    "mailbox"
+    "mailbox_with_mail"
+    "mailbox_with_no_mail"
+    "man"
+    "mans_shoe"
+    "man_with_gua_pi_mao"
+    "man_with_turban"
+    "maple_leaf"
+    "mask"
+    "massage"
+    "meat_on_bone"
+    "mega"
+    "melon"
+    "memo"
+    "mens"
+    "metal"
+    "metro"
+    "microphone"
+    "microscope"
+    "milky_way"
+    "minibus"
+    "minidisc"
+    "mobile_phone_off"
+    "moneybag"
+    "money_with_wings"
+    "monkey_face"
+    "monkey"
+    "monorail"
+    "moon"
+    "mortar_board"
+    "mountain_bicyclist"
+    "mountain_cableway"
+    "mountain_railway"
+    "mount_fuji"
+    "mouse2"
+    "mouse"
+    "movie_camera"
+    "moyai"
+    "m"
+    "muscle"
+    "mushroom"
+    "musical_keyboard"
+    "musical_note"
+    "musical_score"
+    "mute"
+    "nail_care"
+    "name_badge"
+    "neckbeard"
+    "necktie"
+    "negative_squared_cross_mark"
+    "neutral_face"
+    "new_moon"
+    "new_moon_with_face"
+    "new"
+    "newspaper"
+    "ng"
+    "nine"
+    "no_bell"
+    "no_bicycles"
+    "no_entry"
+    "no_entry_sign"
+    "no_good"
+    "no_mobile_phones"
+    "no_mouth"
+    "non-potable_water"
+    "no_pedestrians"
+    "nose"
+    "no_smoking"
+    "notebook"
+    "notebook_with_decorative_cover"
+    "notes"
+    "nut_and_bolt"
+    "o2"
+    "ocean"
+    "octocat"
+    "octopus"
+    "oden"
+    "office"
+    "ok_hand"
+    "ok"
+    "ok_woman"
+    "older_man"
+    "older_woman"
+    "oncoming_automobile"
+    "oncoming_bus"
+    "oncoming_police_car"
+    "oncoming_taxi"
+    "one"
+    "on"
+    "open_file_folder"
+    "open_hands"
+    "open_mouth"
+    "ophiuchus"
+    "o"
+    "orange_book"
+    "outbox_tray"
+    "ox"
+    "package"
+    "page_facing_up"
+    "pager"
+    "page_with_curl"
+    "palm_tree"
+    "panda_face"
+    "paperclip"
+    "parking"
+    "part_alternation_mark"
+    "partly_sunny"
+    "passport_control"
+    "paw_prints"
+    "peach"
+    "pear"
+    "pencil2"
+    "pencil"
+    "penguin"
+    "pensive"
+    "performing_arts"
+    "persevere"
+    "person_frowning"
+    "person_with_blond_hair"
+    "person_with_pouting_face"
+    "phone"
+    "pig2"
+    "pig_nose"
+    "pig"
+    "pill"
+    "pineapple"
+    "pisces"
+    "pizza"
+    "plus1"
+    "point_down"
+    "point_left"
+    "point_right"
+    "point_up_2"
+    "point_up"
+    "police_car"
+    "poodle"
+    "poop"
+    "postal_horn"
+    "postbox"
+    "post_office"
+    "potable_water"
+    "pouch"
+    "poultry_leg"
+    "pound"
+    "pouting_cat"
+    "pray"
+    "princess"
+    "punch"
+    "purple_heart"
+    "purse"
+    "pushpin"
+    "put_litter_in_its_place"
+    "question"
+    "rabbit2"
+    "rabbit"
+    "racehorse"
+    "radio_button"
+    "radio"
+    "rage1"
+    "rage2"
+    "rage3"
+    "rage4"
+    "rage"
+    "railway_car"
+    "rainbow"
+    "raised_hand"
+    "raised_hands"
+    "raising_hand"
+    "ramen"
+    "ram"
+    "rat"
+    "recycle"
+    "red_car"
+    "red_circle"
+    "registered"
+    "relaxed"
+    "relieved"
+    "repeat_one"
+    "repeat"
+    "restroom"
+    "revolving_hearts"
+    "rewind"
+    "ribbon"
+    "rice_ball"
+    "rice_cracker"
+    "rice"
+    "rice_scene"
+    "ring"
+    "rocket"
+    "roller_coaster"
+    "rooster"
+    "rose"
+    "rotating_light"
+    "round_pushpin"
+    "rowboat"
+    "rugby_football"
+    "runner"
+    "running"
+    "running_shirt_with_sash"
+    "ru"
+    "sagittarius"
+    "sailboat"
+    "sake"
+    "sandal"
+    "santa"
+    "sa"
+    "satellite"
+    "satisfied"
+    "saxophone"
+    "school"
+    "school_satchel"
+    "scissors"
+    "scorpius"
+    "scream_cat"
+    "scream"
+    "scroll"
+    "seat"
+    "secret"
+    "seedling"
+    "see_no_evil"
+    "seven"
+    "shaved_ice"
+    "sheep"
+    "shell"
+    "shipit"
+    "ship"
+    "shirt"
+    "shit"
+    "shoe"
+    "shower"
+    "signal_strength"
+    "six"
+    "six_pointed_star"
+    "ski"
+    "skull"
+    "sleeping"
+    "sleepy"
+    "slot_machine"
+    "small_blue_diamond"
+    "small_orange_diamond"
+    "small_red_triangle_down"
+    "small_red_triangle"
+    "smile_cat"
+    "smile"
+    "smiley_cat"
+    "smiley"
+    "smiling_imp"
+    "smirk_cat"
+    "smirk"
+    "smoking"
+    "snail"
+    "snake"
+    "snowboarder"
+    "snowflake"
+    "snowman"
+    "sob"
+    "soccer"
+    "soon"
+    "sos"
+    "sound"
+    "space_invader"
+    "spades"
+    "spaghetti"
+    "sparkle"
+    "sparkler"
+    "sparkles"
+    "sparkling_heart"
+    "speaker"
+    "speak_no_evil"
+    "speech_balloon"
+    "speedboat"
+    "squirrel"
+    "star2"
+    "star"
+    "stars"
+    "station"
+    "statue_of_liberty"
+    "steam_locomotive"
+    "stew"
+    "straight_ruler"
+    "strawberry"
+    "stuck_out_tongue_closed_eyes"
+    "stuck_out_tongue"
+    "stuck_out_tongue_winking_eye"
+    "sunflower"
+    "sunglasses"
+    "sunny"
+    "sunrise_over_mountains"
+    "sunrise"
+    "sun_with_face"
+    "surfer"
+    "sushi"
+    "suspect"
+    "suspension_railway"
+    "sweat_drops"
+    "sweat"
+    "sweat_smile"
+    "sweet_potato"
+    "swimmer"
+    "symbols"
+    "syringe"
+    "tada"
+    "tanabata_tree"
+    "tangerine"
+    "taurus"
+    "taxi"
+    "tea"
+    "telephone"
+    "telephone_receiver"
+    "telescope"
+    "tennis"
+    "tent"
+    "thought_balloon"
+    "three"
+    "thumbsdown"
+    "thumbsup"
+    "ticket"
+    "tiger2"
+    "tiger"
+    "tired_face"
+    "tm"
+    "toilet"
+    "tokyo_tower"
+    "tomato"
+    "tongue"
+    "tophat"
+    "top"
+    "tractor"
+    "traffic_light"
+    "train2"
+    "train"
+    "tram"
+    "triangular_flag_on_post"
+    "triangular_ruler"
+    "trident"
+    "triumph"
+    "trolleybus"
+    "trollface"
+    "trophy"
+    "tropical_drink"
+    "tropical_fish"
+    "truck"
+    "trumpet"
+    "tshirt"
+    "tulip"
+    "turtle"
+    "tv"
+    "twisted_rightwards_arrows"
+    "two_hearts"
+    "two_men_holding_hands"
+    "two"
+    "two_women_holding_hands"
+    "u5272"
+    "u5408"
+    "u55b6"
+    "u6307"
+    "u6708"
+    "u6709"
+    "u6e80"
+    "u7121"
+    "u7533"
+    "u7981"
+    "u7a7a"
+    "uk"
+    "umbrella"
+    "unamused"
+    "underage"
+    "unlock"
+    "up"
+    "us"
+    "vertical_traffic_light"
+    "vhs"
+    "vibration_mode"
+    "video_camera"
+    "video_game"
+    "violin"
+    "virgo"
+    "volcano"
+    "v"
+    "vs"
+    "walking"
+    "waning_crescent_moon"
+    "waning_gibbous_moon"
+    "warning"
+    "watch"
+    "water_buffalo"
+    "watermelon"
+    "wave"
+    "wavy_dash"
+    "waxing_crescent_moon"
+    "waxing_gibbous_moon"
+    "wc"
+    "weary"
+    "wedding"
+    "whale2"
+    "whale"
+    "wheelchair"
+    "white_check_mark"
+    "white_circle"
+    "white_flower"
+    "white_large_square"
+    "white_medium_small_square"
+    "white_medium_square"
+    "white_small_square"
+    "white_square_button"
+    "wind_chime"
+    "wine_glass"
+    "wink"
+    "wolf"
+    "woman"
+    "womans_clothes"
+    "womans_hat"
+    "womens"
+    "worried"
+    "wrench"
+    "x"
+    "yellow_heart"
+    "yen"
+    "yum"
+    "zap"
+    "zero"
+    "zzz"})
+
+(def emoji-regex #"\:[^\\s:]+\:")
+(def emoji-converter (fn [e]
+                       (let [emoji (.substring e 1 (dec (.-length e)))]
+                         (if (valid-emojis emoji)
+                           [:img {:src (str "/static/imgs/emoji/" emoji ".png")
+                                  :class-name "emoji"}]
+                           e))))
+
+(register-enricher! emoji-regex emoji-converter)


break on error

break on error

--- uberjar/src/dda/pallet/dda_managed_ide/main.clj
+++ uberjar/src/dda/pallet/dda_managed_ide/main.clj
@@ -20,17 +20,9 @@
   (:require
     [clojure.string :as str]
     [clojure.tools.cli :as cli]
-    [dda.config.commons.styled-output :as styled]
+    [dda.pallet.core.main-helper :as mh]
     [dda.pallet.core.app :as core-app]
     [dda.pallet.dda-managed-ide.app :as app]))
-
-(def cli-options
-  [["-h" "--help"]
-   ["-s" "--serverspec"]
-   ["-c" "--configure"]
-   ["-t" "--targets example-targets.edn" "edn file containing the targets to install on."
-    :default "localhost-target.edn"]
-   ["-v" "--verbose"]])

 (defn usage [options-summary]
   (str/join
@@ -47,34 +39,30 @@
     "  - has to be a valid DdaIdeDomainConfig (see: https://github.com/DomainDrivenArchitecture/dda-managed-ide)"
     ""]))

-(defn error-msg [errors]
-  (str "The following errors occurred while parsing your command:\n\n"
-       (str/join \newline errors)))
-
-(defn exit [status msg]
-  (println msg)
-  (System/exit status))
-
 (defn -main [& args]
-  (let [{:keys [options arguments errors summary help]} (cli/parse-opts args cli-options)
+  (let [{:keys [options arguments errors summary help]} (cli/parse-opts args mh/cli-options)
         verbose (if (contains? options :verbose) 1 0)]
     (cond
-      help (exit 0 (usage summary))
-      errors (exit 1 (error-msg errors))
-      (not= (count arguments) 1) (exit 1 (usage summary))
+      help (mh/exit 0 (usage summary))
+      errors (mh/exit 1 (mh/error-msg errors))
+      (not= (count arguments) 1) (mh/exit 1 (usage summary))
       (:serverspec options) (if (core-app/existing-serverspec
                                   app/crate-app
                                   {:domain (first arguments)
                                    :targets (:targets options)
                                    :verbosity verbose})
-                                (exit 0 (styled/styled "ALL TESTS PASSED" :green))
-                                (exit 2 (styled/styled "SOME TESTS FAILED" :red)))
+                                (mh/exit-test-passed)
+                                (mh/exit-test-failed))
+      (:configure options) (if (core-app/existing-configure
+                                app/crate-app
+                                {:domain (first arguments)
+                                 :targets (:targets options)})
+                             (mh/exit-default-success)
+                             (mh/exit-default-error))
+      :default (if (core-app/existing-install
+                    app/crate-app
+                    {:domain (first arguments)
+                     :targets (:targets options)})
+                 (mh/exit-default-success)
+                 (mh/exit-default-error)))))

-      (:configure options) (core-app/existing-configure
-                             app/crate-app
-                             {:domain (first arguments)
-                              :targets (:targets options)})
-      :default (core-app/existing-install
-                 app/crate-app
-                 {:domain (first arguments)
-                  :targets (:targets options)}))))


Add data normalization

Add data normalization

--- src/cyanite_fetcher/core.clj
+++ src/cyanite_fetcher/core.clj
@@ -260,12 +260,47 @@
     fdata))

 (defn r-flatter-cleaner
+  "Flatter and clearer based on reducers."
   [data]
   (println "Flatting and clearing data with reducers...")
   (let [frdata (time (doall (into [] (r/remove nil? (r/reduce into [] data)))))]
     (println "Number of rows:" (count frdata))
     (newline)
     frdata))
+
+;;------------------------------------------------------------------------------
+;; Data normalization
+;;------------------------------------------------------------------------------
+
+(defn fill-in
+  "Fill in fetched data with nil metrics for a given time range"
+  [nils [path data]]
+  (hash-map path
+            (->> (group-by :time data)
+                 (merge nils)
+                 (map (comp first val))
+                 (sort-by :time)
+                 (map :metric))))
+
+(defn norm
+  "Normalization."
+  [data rollup to]
+  (println "Running normalization...")
+  (let [ndata
+        (time (doall (let [min-point  (:time (first data))
+                           max-point  (-> to (quot rollup) (* rollup))
+                           nil-points (->> (range min-point (inc max-point) rollup)
+                                           (map (fn [time] {time [{:time time}]}))
+                                           (reduce merge {}))
+                           by-path    (->> (group-by :path data)
+                                           (map (partial fill-in nil-points))
+                                           (reduce merge {}))]
+                       {:from min-point
+                        :to   max-point
+                        :step rollup
+                        :series by-path})))]
+    (newline)
+    ndata))

 ;;------------------------------------------------------------------------------
 ;; Benchmark
@@ -298,8 +333,8 @@
       (flatter data (fn [data] (r/reduce into [] data)) "r/reduce")
       (cleaner reduce-fdata (fn [data] (remove nil? data))  "remove")
       (cleaner reduce-fdata (fn [data] (into [] (r/remove nil? data))) "r/remove")
-      (r-flatter-cleaner data)))
-
+      (let [fcdata (r-flatter-cleaner data)]
+        (norm fcdata rollup to))))
   (println "Finish time:" (tl/format-local-time (tl/local-now) :rfc822)))

 ;;------------------------------------------------------------------------------


fixed namespace

fixed namespace

--- src/granger/models/books.clj
+++ src/granger/models/books.clj
@@ -1,4 +1,4 @@
-(ns granger.model
+(ns granger.models.books
   (:use ring.util.response)
   (:require [somnium.congomongo :as mongo]))


Errant whitespace

Errant whitespace

--- src/foreclojure/data-set.clj
+++ src/foreclojure/data-set.clj
@@ -2,7 +2,6 @@
   (:use [somnium.congomongo]))

 (do
-
   (insert! :problems
            {:_id 1
             :title "Nothing but the Truth"


Do the destructuring in the method signature

--- src/github_changelog/git.clj
+++ src/github_changelog/git.clj
@@ -21,16 +21,16 @@
       (git/git-clone uri dir))))

 (defn- refresh [^Repository repo]
-  (git/git-fetch-all repo)
-  repo)
+  (git/git-fetch-all repo))

-(defn clone [config]
-  (let [{:keys [git-url dir update?]
-         :or   {git-url (gen-url config)
-                dir     (git-path git-url)
-                update? true}} config
-        repo                   (clone-or-load git-url dir)]
-    (if update? (refresh repo) repo)))
+(defn clone [{:keys [git-url dir update?]
+              :or   {git-url (gen-url config)
+                     dir     (git-path git-url)
+                     update? true}
+              :as config}]
+  (let [repo (clone-or-load git-url dir)]
+    (if update? (refresh repo))
+    repo))

 (defn- get-merge-sha [^Repository repo ^Ref tag]
   (let [peeled (.peel repo tag)]


Release modular.bidi 0.6.1 (new bidi dependency)

--- modules/bidi/project.clj
+++ modules/bidi/project.clj
@@ -1,12 +1,12 @@
 ;; Copyright © 2014 JUXT LTD.

-(defproject juxt.modular/bidi "0.6.0"
+(defproject juxt.modular/bidi "0.6.1"
   :description "A modular extension that provides support for bidi routing"
   :url "https://github.com/juxt/modular/tree/master/modules/bidi"
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/MIT"}
   :dependencies [[com.stuartsierra/component "0.2.1"]
-                 [bidi "1.12.0"]
+                 [bidi "1.12.2"]
                  [juxt.modular/ring "0.5.2"]
                  [prismatic/schema "0.2.1"]
                  [prismatic/plumbing "0.2.2"]]


Tidied up GEB.

Tidied up GEB.

--- src/kolmogorov_music/geb.clj
+++ src/kolmogorov_music/geb.clj
@@ -10,47 +10,38 @@
             [kolmogorov-music.coding :as coding]))

 (def geb
-  (let [timing [4 4 8]
-        theme (->> "GEB"
+  (let [theme (->> "GEB"
                    (map coding/char->ascii)
-                   (phrase timing)
+                   (phrase [4 4 8])
                    (canon/canon #(where :pitch coding/ascii->midi %)))
-        bass (->> (phrase timing [-2 -1 0])
-                  (where :pitch (comp scale/lower scale/lower)))
+        bass (phrase [4 4 8] [-2 -1 0])
+        bass2 (phrase (repeat 4 4) (cycle [3 0]))
         decoration (phrase (repeat 64 1/4) (cycle [7 8 9 11 7 6]))
-        arpeggios (->>
-                    [-2 -1 0 0]
-                    (mapthen
-                    #(->> (phrase (repeat 1/2) [[0 2] -3 [0 2] -3 [0 3] -3 [0 2]]) (where :pitch (scale/from %)))
-                    )
-                    (then (phrase (repeat 1/2) [[0 3] -3 [0 2] -3]))
-                    )
-        fiddle (phrase (repeat 32 1/2) (cycle [4 2 2 0 -1]))
-        fiddle2 (phrase (repeat 64 1/4) (cycle [4 2 5 4 5 4 7 7]))
-        bass2 (phrase (repeat 4) [-11 -14 -11 -14])
-        ]
+        grind (->> [-2 -1 0 0]
+                   (mapthen #(->> (phrase (repeat 7 1/2) (interleave [[0 2] [0 2] [0 3] [0 2]] (repeat -3)))
+                                  (where :pitch (scale/from %))))
+                   (then (phrase (repeat 4 1/2) (interleave [[0 3] [0 2]] (repeat -3)))))
+        twiddle (with (phrase (repeat 32 1/2) (cycle [4 2 2 0 -1])) (phrase (repeat 64 1/4) (cycle [4 2 5 4 5 4 7 7])))]
     (->> bass
-         ;(with fiddle fiddle2)
+         (where :pitch (comp scale/lower scale/lower))
+         ;(with twiiddle)
          ;(with decoration)
-         ;(with arpeggios)
+         ;(with grind)
          (where :pitch (comp scale/B scale/minor))
          (with theme)
          (where :time (bpm 90))
          (where :duration (bpm 90)))))

 (comment
-  (live/stop)
   (fx-chorus)
-  (fx-reverb)
-  (fx-distortion)
   (live/jam (var geb))
   )

 ; Instrumentation
 (definst overchauffeur [freq 110 dur 1.0 vol 1.0]
   (-> (sin-osc freq)
+      (+ (* 1/3 (sin-osc (* 2.01 freq))))
       (+ (* 1/2 (sin-osc (* 3.01 freq))))
-      (+ (* 1/3 (sin-osc (* 2.01 freq))))
       (+ (* 1/8 (sin-osc (* 5.01 freq))))
       (+ (* 2 (sin-osc (* 0.5 freq))))
       (clip2 0.7)


Fixed the bug with list lengths

Fixed the bug with list lengths

--- src/longshi/fressian/js.cljs
+++ src/longshi/fressian/js.cljs
@@ -214,9 +214,11 @@
               (seqable? l) (seq l))
             length (count l)]
         (do
-          (if (< length (.-LIST_PACKED_LENGTH_END c/codes))
+          (if (< length (.-LIST_PACKED_LENGTH_END c/ranges))
             (bsp/write! bos (+ length (.-LIST_PACKED_LENGTH_START c/codes)))
-            (bsp/write! bos (.-LIST c/codes)))
+            (do
+              (bsp/write! bos (.-LIST c/codes))
+              (p/write-int! bos length)))
           (doseq [li l]
             (p/write-object! bos li))))
       bos))
@@ -597,7 +599,7 @@
             oa))
         ((.-LIST c/codes))
         (let [oa #js []
-              length (bsp/read-int32! bis)]
+              length (p/read-object! bis)]
           (do
             (dotimes [i length]
               (.push oa (p/read-object! bis)))


Update warn-delete to convention of editor as first arg

--- src/lt/objs/editor/pool.cljs
+++ src/lt/objs/editor/pool.cljs
@@ -138,7 +138,7 @@
                                                          ]})
                               (reload ed)))))))

-(defn warn-delete [f ed]
+(defn warn-delete [ed f]
   (active-warn ed {:header (str "File deleted: " f)
                    :body "This file seems to have been deleted and we've marked it as unsaved."
                    :buttons [{:label "Save as.."
@@ -151,7 +151,7 @@
           :reaction (fn [ws del]
                       (if-let [ed (first (by-path del))]
                         (do
-                          (warn-delete del ed)
+                          (warn-delete ed del)
                           (make-transient-dirty ed)
                           (when-let [ts (:lt.objs.tabs/tabset @ed)]
                             (object/raise ts :tab.updated)))
@@ -160,7 +160,7 @@
                                               false)
                                            (object/by-tag :editor))]
                           (doseq [ed open]
-                            (warn-delete del ed)
+                            (warn-delete ed del)
                             (make-transient-dirty ed))))))

 (behavior ::watched.rename


fixed tests

fixed tests

--- clj/test/bucket_distributor_clj/core_test.clj
+++ clj/test/bucket_distributor_clj/core_test.clj
@@ -141,6 +141,6 @@
                 (.printStackTrace e))))))))

    ;; initial shutdown blocks until release! is performed
-   => [[[nil "bar"] [nil "bing"]] [[nil "bar"] [nil "bing"]]])
+   => [[["foo" "bar"] ["baz" "bing"]] [["foo" "bar"] ["baz" "bing"]]])


Use the right revision during inference, and store the commit infomation.

--- src/circle/backend/build/config.clj
+++ src/circle/backend/build/config.clj
@@ -265,21 +265,23 @@

 (defn infer-build-from-url
   "Assumes url does not have a circle.yml. Examine the source tree, and return a build"
-  [url]
+  [url & {:keys [vcs-revision]}]
   (let [project (project/get-by-url url)
         project-name (or (-> project :name) (infer-project-name url))
         repo (git/default-repo-path url)
         spec (spec/get-spec-for-project project)
         spec-actions (parse-spec-actions spec)
-        vcs-revision (git/latest-local-commit repo)
+        vcs-revision (or vcs-revision (git/latest-local-commit repo))
+        commit-details (git/commit-details repo vcs-revision)
         node (inference/node repo)]
     (build/build
-     (add-project-info project
-                       {:vcs_url url
-                        :vcs_revision vcs-revision
-                        :node node
-                        :actions (inference/infer-actions repo)
-                        :job-name "build-inferred"}))))
+     (merge (add-project-info project
+                              {:vcs_url url
+                               :vcs_revision vcs-revision
+                               :node node
+                               :actions (inference/infer-actions repo)
+                               :job-name "build-inferred"})
+            commit-details))))

 (defn build-from-url
   "Given a project url and a build name, return a build. Helper method for repl"
@@ -290,7 +292,8 @@
       (build-from-config config project
                          :vcs-revision vcs-revision
                          :job-name job-name)
-      (infer-build-from-url url))))
+      (infer-build-from-url url
+                            :vcs-revision vcs-revision))))

 (defn build-from-json
   "Given a parsed github commit hook json, return a build that needs to be run, or nil"


Use Codemirror version 3.15

Use Codemirror version 3.15

--- src/clj/learndatalogtoday/views.clj
+++ src/clj/learndatalogtoday/views.clj
@@ -24,7 +24,7 @@
   [:html
    [:head
     (include-css "/third-party/bootstrap/css/bootstrap.css")
-    (include-css "/third-party/codemirror-3.14/lib/codemirror.css")
+    (include-css "/third-party/codemirror-3.15/lib/codemirror.css")
     (include-css "/style.css")
     [:title "Learn Datalog Today!"]]
    [:body
@@ -39,8 +39,8 @@
      (row [:div.exercises {:style "margin-top: 14px"} exercises])
      (row (footer))]
     (include-js "/third-party/jquery/jquery-1.10.1.min.js")
-    (include-js "/third-party/codemirror-3.14/lib/codemirror.js")
-    (include-js "/third-party/codemirror-3.14/mode/clojure/clojure.js")
+    (include-js "/third-party/codemirror-3.15/lib/codemirror.js")
+    (include-js "/third-party/codemirror-3.15/mode/clojure/clojure.js")
     (include-js "/third-party/bootstrap/js/bootstrap.js")
     (include-js "/third-party/pagedown/Markdown.Converter.js")
     (include-js "/app.js")


allowed Hardwired Corp IDs to have agendas out of faction

--- src/cljs/netrunner/deckbuilder.cljs
+++ src/cljs/netrunner/deckbuilder.cljs
@@ -89,14 +89,14 @@

 (defn allowed?
   "Checks if a card is allowed in deck of a given identity - not accounting for influence"
-  [card {:keys [side faction title] :as identity}]
+  [card {:keys [side faction setname code] :as identity}]
   (and (not= (:type card) "Identity")
        (= (:side card) side)
        (or (not= (:type card) "Agenda")
            (= (:faction card) "Neutral")
            (= (:faction card) faction)
-           (= title "The Shadow: Pulling the Strings"))
-       (or (not= title "Custom Biotics: Engineered for Success")
+           (= setname "Draft"))
+       (or (not= code "03002") ; Custom Biotics: Engineered for Success
            (not= (:faction card) "Jinteki"))))

 (defn load-decks [decks]