Add resources to manipulate user visibility records: dismiss, dismiss-all, follow and unfollow.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -163,6 +163,52 @@
      :existing-entries (api-common/rep entries)}
     false))

+(defn- valid-entry-new-update? [conn ctx org-slug entry-uuid user action-type]
+  (timbre/info "Valid new update for" entry-uuid "from user" (:user-id user) "action" action-type)
+  (if-let* [existing-entry (entry-res/get-entry conn entry-uuid)
+            existing-org (or (:existing-org ctx) (org-res/get-org conn org-slug))
+            existing-board (or (:existing-board ctx) (board-res/get-board conn (:board-uuid existing-entry)))]
+    ;; Merge the existing entry with the new updates
+    (let [user-visibility (or (some (fn [[k v]] (when (= k (-> user :user-id keyword)) v)) (:user-visibility existing-entry))
+                              {})
+          updated-user-visibility (cond
+                                    (= action-type :dismiss)
+                                    (assoc user-visibility :dismiss-at (:data ctx))
+                                    (= action-type :follow)
+                                    (assoc user-visibility :follow true)
+                                    (= action-type :unfollow)
+                                    (assoc user-visibility :follow false))
+          updated-entry (assoc-in existing-entry [:user-visibility (keyword (:user-id user))] updated-user-visibility)
+          dismiss-at (:data ctx)]
+      (timbre/info "User visibility" user-visibility "updated:" updated-user-visibility)
+      (if (and (or (not= action-type :dismiss)
+                   (and (= action-type :dismiss)
+                        (lib-schema/valid? lib-schema/ISO8601 dismiss-at)))
+               (lib-schema/valid? common-res/Entry updated-entry))
+        {:existing-org (api-common/rep existing-org)
+         :existing-board (api-common/rep existing-board)
+         :existing-entry (api-common/rep existing-entry)
+         :updated-entry (api-common/rep updated-entry)}
+        [false, {:updated-entry (api-common/rep updated-entry)}])) ; invalid update
+
+    true)) ; no existing entry, so this will fail existence check later
+
+(defn- valid-dismiss-all-update? [conn ctx org-slug user]
+  (if-let* [existing-org (or (:existing-org ctx) (org-res/get-org conn org-slug))
+            existing-entries (entry-res/list-all-entries-for-inbox conn (:uuid existing-org) (:user-id user) :asc (db-common/current-timestamp) :before)
+            dismiss-at (:data ctx)
+            updated-entries (map #(let [user-vis (get-in % [:user-visibility (keyword (:user-id user))] {})]
+                                    (assoc-in % [:user-visibility (keyword (:user-id user))] (assoc user-vis :dismiss-at dismiss-at)))
+                              existing-entries)]
+    (if (and (lib-schema/valid? lib-schema/ISO8601 dismiss-at)
+             (every? #(lib-schema/valid? common-res/Entry %) updated-entries))
+      {:existing-org (api-common/rep existing-org)
+       :existing-entries (api-common/rep existing-entries)
+       :updated-entries (api-common/rep updated-entries)}
+      false)
+
+    true)) ; no existing entry, so this will fail existence check later
+
 ;; ----- Actions -----

 (defn- share-entry [conn ctx entry-for]
@@ -277,6 +323,47 @@
       (timbre/info "Updated entry for:" entry-for)
       (notification/send-trigger! (notification/->trigger :update org board {:old entry :new final-entry} user nil))
       {:updated-entry (api-common/rep (assoc final-entry :board-name (:name board)))})
+
+    (do (timbre/error "Failed updating entry:" entry-for) false)))
+
+(defn- update-entry-new [conn ctx entry-for action-type]
+  (timbre/info "Updating entry for:" entry-for)
+  (if-let* [org (:existing-org ctx)
+            board (:existing-board ctx)
+            user (:user ctx)
+            entry (:existing-entry ctx)
+            updated-entry (:updated-entry ctx)
+            final-entry (entry-res/update-entry! conn (:uuid updated-entry) updated-entry user)
+            dismiss-at (:data ctx)]
+    (let [notify-map (cond
+                      (= action-type :dismiss)
+                      {:dismiss-at dismiss-at}
+                      (= action-type :follow)
+                      {:follow true}
+                      (= action-type :unfollow)
+                      {:unfollow true})]
+      (timbre/info "Updated entry new for:" entry-for "action:" action-type)
+      (notification/send-trigger! (notification/->trigger action-type org board {:old entry :new updated-entry :inbox-action notify-map} user nil))
+      {:updated-entry (api-common/rep final-entry)})
+
+    (do (timbre/error "Failed updating entry:" entry-for) false)))
+
+(defn- inbox-dismiss-all [conn ctx entry-for]
+  (timbre/info "Dismiss all entries for:" entry-for)
+  (if-let* [org (:existing-org ctx)
+            user (:user ctx)
+            existing-entries (:existing-entries ctx)
+            final-entries (map
+                            #(entry-res/update-entry! conn (:uuid %) % user)
+                            existing-entries)
+            dismiss-at (:data ctx)]
+    (if (every? #(lib-schema/valid? common-res/Entry %) final-entries)
+      (do
+        (timbre/info "Dismissed all entries for:" entry-for)
+        (doseq [entry final-entries]
+          (notification/send-trigger! (notification/->trigger :dismiss org nil {:new entry :inbox-action {:dismiss-at dismiss-at}} user nil)))
+        {:updated-entries (api-common/rep final-entries)})
+      false)

     (do (timbre/error "Failed updating entry:" entry-for) false)))

@@ -885,6 +972,115 @@
   :handle-unprocessable-entity (fn [ctx]
     (api-common/unprocessable-entity-response (map #(schema/check common-res/FollowUp %) (:follow-ups ctx)))))

+(defresource inbox-dismiss-all [conn org-slug]
+  (api-common/open-company-authenticated-resource config/passphrase) ; verify validity and presence of required JWToken
+  :allowed-methods [:options :post]
+
+  ;; Authorization
+  :allowed? (by-method {
+    :options true
+    :post (fn [ctx] (access/allow-members conn org-slug (:user ctx)))})
+
+  ;; Media type client accepts
+  :available-media-types (by-method {
+                            :post [mt/entry-media-type]})
+  :handle-not-acceptable (by-method {
+                            :post (api-common/only-accept 406 mt/entry-media-type)})
+
+  ;; Data handling
+  :new? false
+  :respond-with-entity? true
+
+  ;; Validations
+  :processable? (by-method {
+    :options true
+    :post (fn [ctx] (valid-dismiss-all-update? conn ctx org-slug (:user ctx)))})
+
+  ;; Possibly no data to handle
+  :malformed? (by-method {
+    :options false
+    :post (fn [ctx] (api-common/malformed-json? ctx true))}) ; allow nil
+
+  ;; Existentialism
+  :can-post-to-missing? false
+  :exists? (fn [ctx] (if-let* [_slugs? (slugify/valid-slug? org-slug)
+                               org (or (:existing-org ctx)
+                                       (org-res/get-org conn org-slug))
+                               org-uuid (:uuid org)]
+                        {:existing-org (api-common/rep org)}
+                        false))
+
+  ;; Actions
+  :post! (fn [ctx]
+           (inbox-dismiss-all conn ctx org-slug))
+
+  :handle-unprocessable-entity (fn [ctx]
+    (api-common/unprocessable-entity-response (:updated-entries ctx))))
+
+(defresource inbox [conn org-slug board-slug entry-uuid action-type]
+  (api-common/open-company-authenticated-resource config/passphrase) ; verify validity and presence of required JWToken
+  :allowed-methods [:options :post]
+
+  ;; Authorization
+  :allowed? (by-method {
+    :options true
+    :post (fn [ctx] (access/allow-members conn org-slug (:user ctx)))})
+
+  ;; Media type client accepts
+  :available-media-types (by-method {
+                            :post [mt/entry-media-type]})
+  :handle-not-acceptable (by-method {
+                            :post (api-common/only-accept 406 mt/entry-media-type)})
+
+  ;; Data handling
+  :new? false
+  :respond-with-entity? true
+
+  ;; Validations
+  :processable? (by-method {
+    :options true
+    :post (fn [ctx] (valid-entry-new-update? conn ctx org-slug entry-uuid (:user ctx) action-type))})
+
+  ;; Possibly no data to handle
+  :malformed? (by-method {
+    :options false
+    :post (fn [ctx] (api-common/malformed-json? ctx true))}) ; allow nil
+
+  ;; Existentialism
+  :can-post-to-missing? false
+  :exists? (fn [ctx] (if-let* [_slugs? (and (slugify/valid-slug? org-slug)
+                                            (slugify/valid-slug? board-slug))
+                               org (or (:existing-org ctx)
+                                       (org-res/get-org conn org-slug))
+                               org-uuid (:uuid org)
+                               entry (or (:existing-entry ctx)
+                                         (entry-res/get-entry conn entry-uuid))
+                               board (board-res/get-board conn (:board-uuid entry))
+                               comments (or (:existing-comments ctx)
+                                            (entry-res/list-comments-for-entry conn (:uuid entry)))
+                               reactions (or (:existing-reactions ctx)
+                                             (entry-res/list-reactions-for-entry conn (:uuid entry)))]
+                        {:existing-org (api-common/rep org) :existing-board (api-common/rep board)
+                         :existing-entry (api-common/rep entry)
+                         :existing-comments (api-common/rep comments)
+                         :existing-reactions (api-common/rep reactions)}
+                        false))
+
+  ;; Actions
+  :post! (fn [ctx]
+           (update-entry-new conn ctx (s/join " " [org-slug board-slug entry-uuid]) action-type))
+
+  ;; Responses
+  :handle-ok (fn [ctx] (entry-rep/render-entry (:existing-org ctx)
+                                               (:existing-board ctx)
+                                               (:updated-entry ctx)
+                                               (:existing-comments ctx)
+                                               (reaction-res/aggregate-reactions (:existing-reactions ctx))
+                                               (:access-level ctx)
+                                               (-> ctx :user :user-id)))
+  :handle-unprocessable-entity (fn [ctx]
+    (api-common/unprocessable-entity-response (:updated-entry ctx))))
+
 ;; ----- Routes -----

 (defn routes [sys]
@@ -965,4 +1161,20 @@
       (ANY "/orgs/:org-slug/boards/:board-slug/entries/:entry-uuid/follow-up/:follow-up-uuid/complete"
         [org-slug board-slug entry-uuid follow-up-uuid]
         (pool/with-pool [conn db-pool]
-          (follow-up conn org-slug board-slug entry-uuid follow-up-uuid))))))+          (follow-up conn org-slug board-slug entry-uuid follow-up-uuid)))
+      (ANY "/orgs/:org-slug/inbox/dismiss-all"
+        [org-slug]
+        (pool/with-pool [conn db-pool]
+          (inbox-dismiss-all conn org-slug)))
+      (ANY "/orgs/:org-slug/boards/:board-slug/entries/:entry-uuid/inbox/dismiss"
+        [org-slug board-slug entry-uuid]
+        (pool/with-pool [conn db-pool]
+          (inbox conn org-slug board-slug entry-uuid :dismiss)))
+      (ANY "/orgs/:org-slug/boards/:board-slug/entries/:entry-uuid/inbox/follow"
+        [org-slug board-slug entry-uuid]
+        (pool/with-pool [conn db-pool]
+          (inbox conn org-slug board-slug entry-uuid :follow)))
+      (ANY "/orgs/:org-slug/boards/:board-slug/entries/:entry-uuid/inbox/unfollow"
+        [org-slug board-slug entry-uuid]
+        (pool/with-pool [conn db-pool]
+          (inbox conn org-slug board-slug entry-uuid :unfollow))))))


Add new cgen: varlag

Add new cgen: varlag

--- src/overtone/sc/cgens/line.clj
+++ src/overtone/sc/cgens/line.clj
@@ -1,5 +1,20 @@
 (ns overtone.sc.cgens.line
   (:use [overtone.sc defcgen ugens]))
+
+(defcgen varlag
+  "Variable shaped lag"
+  [in     {:default 0 :doc "Input to lag"}
+   time   {:default 0.1 :doc "Lag time in seconds"}
+   curvature {:default 0 :doc "Control curvature if shape input is 5 (default). 0 means linear, positive and negative numbers curve the segment up and down."}
+   shape  {:default 5 :doc "Shape of curve. 0: step, 1: linear, 2: exponential, 3: sine, 4: welch, 5: custom (use curvature param), 6: squared, 7: cubed, 8: hold"}
+
+   ]
+  "Similar to Lag but with other curve shapes than exponential. A change on the input will take the specified time to reach the new value. Useful for smoothing out control signals."
+  (:kr
+   (let [gate (+ (+ (impulse:kr 0 0) (> (abs (hpz1 in)) 0))
+                 (> (abs (hpz1 time)) 0) )]
+     (env-gen [in 1 -99 -99 in time shape curvature] gate))))
+

 (defcgen lin-lin
   "Map values from one linear range to another"


Maximum conversation size; fixes #74. Still need to find optimal cuttoffs based on memory and compute time.

--- src/polismath/conversation.clj
+++ src/polismath/conversation.clj
@@ -71,16 +71,45 @@
                           :base-iters 10
                           :base-k 50
                           :max-k 12
-                          :group-iters 10}
+                          :group-iters 10
+                          :max-ptpts 100000
+                          :max-cmts 1000}
                     opts))

    :zid         (plmb/fnk [conv votes]
                   (or (:zid conv)
                       (:zid (first votes))))

-   :rating-mat  (plmb/fnk [conv votes]
+   :customs     (plmb/fnk [conv votes opts']
+                  ; Decides whether there is room for new ptpts/cmts, and which votes should be allowed in
+                  ; based on which ptpts/cmts have already been seen. This is a simple prevention against
+                  ; conversations that get too large. Returns {:pids :tids :votes}, where the first two kv
+                  ; pairs are persisted and built upon and persisted; :votes is used downstream and tossed
+                  (reduce
+                    (fn [{:keys [pids tids] :as result}
+                         {:keys [pid  tid]  :as vote}]
+                      (let [pid-room (< (count pids) (:max-ptpts opts'))
+                            tid-room (< (count tids) (:max-cmts opts'))
+                            pid-in   (pids pid)
+                            tid-in   (tids tid)]
+                        (if (and (or pid-room pid-in)
+                                 (or tid-room tid-in))
+                          (assoc result
+                                 :pids  (conj (:pids result)  pid)
+                                 :tids  (conj (:tids result)  tid)
+                                 :votes (conj (:votes result) vote))
+                          result)))
+                    ; Customs collection off which to base reduction; note that votes get cleared out
+                    (assoc (or (:customs conv) {:pids #{} :tids #{}})
+                      :votes [])
+                    votes))
+
+   :keep-votes  (plmb/fnk [customs]
+                  (:votes customs))
+
+   :rating-mat  (plmb/fnk [conv keep-votes]
                   (update-nmat (:rating-mat conv)
-                               (map (fn [v] (vector (:pid v) (:tid v) (:vote v))) votes)))
+                               (map (fn [v] (vector (:pid v) (:tid v) (:vote v))) keep-votes)))

    :n           (plmb/fnk [rating-mat]
                   (count (rownames rating-mat)))
@@ -90,6 +119,7 @@

    :user-vote-counts
                 (plmb/fnk [rating-mat]
+                  ; For deciding in-conv below; filter ptpts based on how much they've voted
                   (mapv
                     (fn [rowname row] [rowname (count (remove nil? row))])
                     (rownames rating-mat)
@@ -298,11 +328,16 @@
     (let [ptpts   (rownames (:rating-mat conv))
           n-ptpts (count (distinct (into ptpts (map :pid votes))))]
       (println "N-ptpts:" n-ptpts)
-      ; dispatch to the appropriate function
-      ((cond
-         (> n-ptpts large-cutoff)   large-conv-update
-         :else             small-conv-update)
-            {:conv conv :votes votes :opts opts}))
+      (->
+        ; dispatch to the appropriate function
+        ((cond
+           (> n-ptpts large-cutoff)   large-conv-update
+           :else             small-conv-update)
+              {:conv conv :votes votes :opts opts})
+        ; Remove the :votes key from customs; not needed for persistence
+        (assoc-in
+          [:customs :votes]
+          [])))
     (catch Exception e
       ; XXX - hmm... have to figure out how to deal with this hook in production. Shouldn't save things to
       ; disk that are too big, and in fact won't be able to save to disk at all on heroku


Reduce test size for CI

Reduce test size for CI

--- test/onyx/metrics/throughput_test.clj
+++ test/onyx/metrics/throughput_test.clj
@@ -29,7 +29,7 @@

 (def peer-group (onyx.api/start-peer-group peer-config))

-(def n-messages 10000000)
+(def n-messages 100000)

 (def batch-size 20)


Rename test

Rename test

--- test/silly_image_store/store_test.clj
+++ test/silly_image_store/store_test.clj
@@ -9,7 +9,7 @@
     (is (= (class file) java.io.File))
     (is (= (.getPath file) path)))

-  (testing "loading a file"
+  (testing "loading an image"
     (is-file-with-path (load-image test-basedir "tubes.jpg") "test/fixtures/tubes.jpg")
     (is-file-with-path (load-image "test" "fixtures" "tubes.jpg")"test/fixtures/tubes.jpg")
     (is (nil? (load-image "somewhere" "doesnt-exist.png"))))


uncomment

uncomment

--- perf-test/clj/reitit/opensensors_perf_test.clj
+++ perf-test/clj/reitit/opensensors_perf_test.clj
@@ -581,23 +581,23 @@
     (b! "reitit-ring" reitit-ring-f)

     ;;   385ns (java-segment-router, no injects)
-    #_(b! "reitit-ring-fast" reitit-ring-fast-f)
+    (b! "reitit-ring-fast" reitit-ring-fast-f)

     ;;  2553ns (linear-router)
     ;;   630ns (segment-router-backed)
-    #_(b! "reitit-ring-linear" reitit-ring-linear-f)
+    (b! "reitit-ring-linear" reitit-ring-linear-f)

     ;;  2137ns
     (b! "calfpath-walker" calfpath-walker-f)

     ;;  4774ns
-    #_(b! "calfpath-unroll" calfpath-unroll-f)
+    (b! "calfpath-unroll" calfpath-unroll-f)

     ;;  2821ns
     (b! "pedestal" pedestal-f)

     ;;  4803ns
-    #_(b! "calfpath-macros" calfpath-macros-f)
+    (b! "calfpath-macros" calfpath-macros-f)

     ;; 11615ns
     (b! "compojure" compojure-f)


wrap-params now does not parse params if they already exist in the request map

--- src/ring/middleware/params.clj
+++ src/ring/middleware/params.clj
@@ -70,8 +70,11 @@
   (fn [request]
     (let [encoding (or (:encoding opts)
                        (:character-encoding request)
-                       "UTF-8")]
-      (-> request
-        (assoc-form-params encoding)
-        (assoc-query-params encoding)
-        handler))))
+                       "UTF-8")
+          request  (if (:form-params request)
+                     request
+                     (assoc-form-params request encoding))
+          request  (if (:query-params request)
+                     request
+                     (assoc-query-params request encoding))]
+      (handler request))))


Moving aggregation id log

Moving aggregation id log

--- src/qu/cache.clj
+++ src/qu/cache.clj
@@ -79,12 +79,12 @@
   ([database query not-found]
      (with-db database
        (let [collection (query-to-key query)]
+		(log/info "FOUND Aggregation - ID:" collection)
          (if (coll/exists? collection)
            (do (metrics/increment "cache.hit.count")
              (extract-result collection query))
            (do (metrics/increment "cache.wait.count")
-               not-found))
-        (log/info "FOUND Cached Aggregation - Id:" collection)))))
+               not-found))))))

 (defn add-to-cache
   "Add the specified aggregation to the cache by running it through


Fixed component dereferencing in darwin

Fixed component dereferencing in darwin

--- src/polismath/darwin/server.clj
+++ src/polismath/darwin/server.clj
@@ -232,7 +232,7 @@

 (defn filename-request-handler
   "Given aws-creds, returns a function handler function which responds to requests for an existing file on AWS."
-  [darwin {:keys [params postgres] :as request}]
+  [{:as darwin :keys [params postgres]} :as request]
   (let [{:keys [filename zinvite]} params
         zid (db/get-zid-from-zinvite postgres zinvite)]
     (if (= (get (get-export-status darwin filename zid) "status") "complete")
@@ -270,7 +270,7 @@
      :body    (str "Export is complete. Download at the Location url specified in the header (" url ")")}))

 (defn get-datadump-status-handler
-  [darwin {:keys [params postgres] :as request}]
+  [{:as darwin :keys [params postgres]} request]
   (let [{:keys [filename zinvite]} params
         zid (db/get-zid-from-zinvite postgres zinvite)]
     (case (-> (get-export-status darwin filename zid) (get "status"))
@@ -364,7 +364,7 @@
 (defn get-datadump-handler
   "Main handler function; Attempts to return a datadump file within within a set amount of time, and if it can't, will
   respond with a 202, and set up a process for obtaining the results once they're done."
-  [darwin {:keys [params postgres] :as request}]
+  [{:as darwin :keys [params postgres]} :as request]
   (let [params (parsed-params datadump-params params)
         ;; Check validity of params here
         _ (log/info "Handling datadump request with params:" (with-out-str (prn params)))


fix bad merge by replacing my-coll with original vars

--- src-cljs/cuttle/projects.cljs
+++ src-cljs/cuttle/projects.cljs
@@ -60,7 +60,7 @@
   (let [builds (:builds (:cljsbuild prj))
         out-dirs (map #(get-in % [:compiler :output-dir]) builds)
         out-paths (map #(get-in % [:compiler :output-to]) builds)]
-    (if (and (not (empty? my-coll)) (not (empty? my-coll)))
+    (if (and (not (empty? out-dirs)) (not (empty? out-paths)))
       ;; then
       (if-not (and (apply distinct? out-dirs)
                  (apply distinct? out-paths))


Remove debug.

Remove debug.

--- src/tryclojure/models/eval.clj
+++ src/tryclojure/models/eval.clj
@@ -48,8 +48,6 @@
 (defmulti run-story-command (fn [command expr] command))

 (defmethod run-story-command "hear" [command expr]
-  (println command)
-  (println expr)
   (if-let [story-name (second (str/split expr #" "))]
     (let [file-path (str/lower-case (str "stories/" story-name ".is"))
           story-str (slurp file-path)]


Open element options when shape is selected.

--- src/uxbox/main/data/shapes.cljs
+++ src/uxbox/main/data/shapes.cljs
@@ -341,10 +341,11 @@
   (reify
     rs/UpdateEvent
     (-apply-update [_ state]
-      (let [selected (get-in state [:workspace :selected])]
-        (if (contains? selected id)
-          (update-in state [:workspace :selected] disj id)
-          (update-in state [:workspace :selected] conj id))))))
+      (let [selected (get-in state [:workspace :selected])
+            state (if (contains? selected id)
+                    (update-in state [:workspace :selected] disj id)
+                    (update-in state [:workspace :selected] conj id))]
+        (update-in state [:workspace :flags] conj :element-options)))))

 ;; --- Select Shapes


CMR-1888: Wrap argument in pr-str

CMR-1888: Wrap argument in pr-str

--- transmit-lib/src/cmr/transmit/kms.clj
+++ transmit-lib/src/cmr/transmit/kms.clj
@@ -69,7 +69,9 @@
     (when-not (= expected-subfield-names subfield-names)
       (throw (Exception.
                (format "Expected subfield names for %s to be %s, but were %s."
-                       (name keyword-scheme) expected-subfield-names (pr-str subfield-names)))))))
+                       (name keyword-scheme)
+                       (pr-str expected-subfield-names)
+                       (pr-str subfield-names)))))))

 (defn- parse-entries-from-csv
   "Parses the CSV returned by the GCMD KMS. It is expected that the CSV will be returned in a


CMR-3555: fixed an indentation.

CMR-3555: fixed an indentation.

--- system-int-test/test/cmr/system_int_test/search/collection_science_keyword_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_science_keyword_search_test.clj
@@ -136,7 +136,7 @@
                              {field {:0 {:category "Hurricane"
                                          :topic "Popular"}
                                      :1 {:term "Extreme"}}
-                            (str "options[" (name field) "][or]") "true"})))))
+                              (str "options[" (name field) "][or]") "true"})))))

     (testing "search by science keywords, multiple and legacy :or format"
       (is (d/refs-match? [coll2 coll6]


update swagger arena defaults

update swagger arena defaults

--- src/wombats/handlers/arena.clj
+++ src/wombats/handlers/arena.clj
@@ -6,14 +6,14 @@

 (def ^:private arena-body-sample
   #:arena{:name "Arena Name"
-          :width 50
-          :height 50
+          :width 20
+          :height 20
           :shot-damage 10
           :smoke-duration 3
           :food 10
           :poison 10
-          :stone-walls 50
-          :wood-walls 50
+          :steel-walls 10
+          :wood-walls 10
           :zakano 4
           :perimeter true})


Log errors when inserting events breaks

Log errors when inserting events breaks

--- src/rill/event_store/psql.clj
+++ src/rill/event_store/psql.clj
@@ -65,10 +65,12 @@
                                   (nippy/freeze e)])
                                events))
            true
-           (catch org.postgresql.util.PSQLException e
-             nil)
            (catch java.sql.BatchUpdateException e
-             nil)))))
+             (when-not (= (.getSQLState e) "23505")
+               (log/error e)
+               (log/error (.getNextException e))
+               (throw e))
+             false)))))

 (defn psql-event-store [spec & [{:keys [page-size] :or {page-size 20}}]]
   {:pre [(integer? page-size)]}


Corrected typo in rule

Corrected typo in rule

--- resources/rules/post_identifier_merge/temp/abstraction/gene_or_gene_product_abstraction.clj
+++ resources/rules/post_identifier_merge/temp/abstraction/gene_or_gene_product_abstraction.clj
@@ -1,11 +1,8 @@
 ;; ----------------------------------------------------
 ;; --------- Gene or Gene Product Abstraction ---------
 ;; ----------------------------------------------------
-;;TODO the restrictions need to be properly reified
-
 `{:name "gene-or-gene-product-abstraction"
   :description "This rule creates an absraction for referring to genes or gene products"
-  ;; this needs to be hashed and have proper classes
   :head ((?/gene_product rdfs/subClassOf ?/gene_or_gene_product))

   :body ((?/gene rdf/type kbio/GeneSpecificGClass)
@@ -14,7 +11,7 @@

          (?/has_indirect_template_restriction owl/someValuesFrom ?/gene)
          (?/has_indirect_template_restriction owl/onProperty obo/pr#has_gene_template) ; PR:has_gene_template
-         (?/gene_product rdfs/subClassOf?/has_indirect_template_restriction))
+         (?/gene_product rdfs/subClassOf? /has_indirect_template_restriction))

   :options {:magic-prefixes [["franzOption_clauseReorderer" "franz:identity"]]}
   }


CMR-6161 autocomplete api calls

CMR-6161 autocomplete api calls

--- search-app/src/cmr/search/api/autocomplete.clj
+++ search-app/src/cmr/search/api/autocomplete.clj
@@ -1,7 +1,10 @@
 (ns cmr.search.api.autocomplete
   "Defines the API for autocomplete-suggest in the CMR."
   (:require
+    [cmr.common.log :refer (debug info warn error)]
+    [cmr.common.services.errors :as svc-errors]
     [cmr.search.services.autocomplete-service :as ac]
+    [cmr.search.services.query-service :as qs]
     [cmr.common-app.api.routes :as common-routes]
     [cmr.common.mime-types :as mt]
     [compojure.core :refer :all]))
@@ -11,22 +14,24 @@

 (defn- get-autocomplete-suggestions
   "Invokes Elasticsearch for autocomplete query result"
-  [query types]
-  (if query
-    {:status  200
-     :headers {common-routes/CONTENT_TYPE_HEADER (str (mt/format->mime-type :json) "; charset=utf-8")}
-     :body    {:query   query
-               :results (ac/autocomplete query)}}
-    {:status  400
-     :headers {common-routes/CONTENT_TYPE_HEADER (str (mt/format->mime-type :json) "; charset=utf-8")}
-     :body    {:message "No query term provided"
-               :usage   "/autocomplete?q=<value>"}}))
+  [ctx params]
+  (let [term (:q params)]
+    (if term
+      (let [results (ac/autocomplete ctx term)]
+        {:status  200
+         :headers {common-routes/CONTENT_TYPE_HEADER (str (mt/format->mime-type :json) "; charset=utf-8")
+                   common-routes/CORS_ORIGIN_HEADER  "*"}
+         :body    {:query   term
+                   :results results}})
+      (svc-errors/throw-service-errors
+       :bad-request
+       ["Missing param [q]" "Usage [/autocomplete?q=<term>]"]))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Route Definitions

 (def autocomplete-api-routes
   (context "/autocomplete" []
-     (GET "/"
-        [q types]
-        (get-autocomplete-suggestions q types))))
+           (GET "/"
+                {params :params ctx :request-context}
+                (get-autocomplete-suggestions ctx params))))


pig latin to english clojure, need to fix pig latin validator

--- tech-int/src/tech_int/core.clj
+++ tech-int/src/tech_int/core.clj
@@ -33,20 +33,69 @@

 ;;; PIG LATIN ;;;

-(use '[clojure.string :only (join split capitalize)])
+(use '[clojure.string :only (join split capitalize ends-with?)])

 (defn toPigLatin
     [string]
     (str (join (rest string)) (first string) (str "ay"))
 )

+(defn checkIfPigLatin
+    [array]
+    (loop [array array
+           i 0]
+        (if (< i (count array))
+            (if (not= (ends-with? (array i) "ay"))
+                false
+                true
+            )
+            (recur array (inc i))
+        )
+    )
+
+)
+
+(defn toEnglish
+    [string]
+    (def noAy (drop-last 2 string))
+    (def restOfWord (drop-last noAy))
+    (def firstLetter (last noAy))
+    (apply str firstLetter restOfWord)
+)
+
 (defn -pigLatin []
+    (println "1. English to pig latin")
+    (println "2. Pig latin to english")
+    (def choice (Integer. (read-line)))
     (println "Enter a phrase:")
     (def inputPhrase (read-line))
     (println "--")
     (def inputArray (split inputPhrase #"\s+"))
-    (def pigLatinArray (mapv toPigLatin inputArray))
-    (println (capitalize (join " " pigLatinArray)))
+    (if (< choice 3)
+        (if (= choice 1)
+            (do
+                (def pigLatinArray (mapv toPigLatin inputArray))
+                (println (capitalize (join " " pigLatinArray)))
+            )
+            (do
+                (if (checkIfPigLatin inputArray)
+                    (do
+                        (def englishArray (mapv toEnglish inputArray))
+                        (println (capitalize (join " " englishArray)))
+                    )
+                    (do
+                        (println "Phrase is not pig latin, please correct and try again.")
+                        (-pigLatin)
+                    )
+                )
+            )
+        )
+        (do
+            (println "Sorry, invalid choice")
+            (-pigLatin)
+        )
+    )
+
     (println "--")
 )


Drawing nodes from UI

Drawing nodes from UI

Trivial implementation, needs to be queried explicitly from an input and
does not handle backend errors yet.

--- src-cljs/tropefest/core.cljs
+++ src-cljs/tropefest/core.cljs
@@ -5,6 +5,16 @@
             [reagent-forms.core :refer [bind-fields]]
             [ajax.core :refer [POST]])
   (:require-macros [secretary.core :refer [defroute]]))
+
+
+(defn row [label & body]
+  [:div.row
+   [:div.col-md-2 [:span label]]
+   [:div.col-md-3 body]])
+
+(defn text-input [id label]
+  (row label [:input.form-control {:field :text
+                                   :id    id}]))

@@ -60,11 +70,13 @@
   [:div
    [:main]
    [:div "this is the story of tropefest... work in progress"]
-   ]
-  )
+   ])

 ; Graph!
+
+
+(def state (atom {:graph null}))

 (-> js/sigma .-classes .-graph (.addMethod "neighbors",
                                            (fn [node-id]
@@ -78,8 +90,8 @@
 (defn in-seq? [s x]
   (some? (some #{x} s)))

-(defn create-graph []
-  (js/sigma.parsers.json "/api/network/Anime/CowboyBebop" ; "/static/test-data/basic-graph.json"
+(defn create-graph [code]
+  (js/sigma.parsers.json (str js/context "/api/network/" code)
                          (clj->js {
                                    :renderer {:container (.getElementById js/document "container")
                                               :type      "canvas"
@@ -88,6 +100,10 @@
                                               :edgeLabelSize    "proportional"
                                               }})
                          (fn [s]
+                           ; Feel a bit dirty about using an atom here, but calling this function
+                           ; is not returning the sigma object
+                           (swap! state assoc :graph s)
+                           ; Set the colors
                            (goog.object/forEach (-> s .-graph .nodes)
                                                 #(aset % "originalColor" "#ff0000"))
                            (goog.object/forEach (-> s .-graph .edges)
@@ -113,18 +129,26 @@
                                   ))
                          ))

+(defn redraw-graph []
+  (let [current (:graph @state)]                            ; Must be set by importer on creation
+    (if current
+      (do
+        (.kill current)
+        (swap! state assoc :graph nil)))
+    (create-graph (-> (.getElementById js/document "trope-code") .-value))
+    ))
+

 (defn plot []
   [:div
+   (text-input :trope-code "Trope code:")
    [:input {:type     "button" :value "Graph!"
-            :on-click #(create-graph)}]
+            :on-click #(redraw-graph)}]
    [:div {:id "container"}]])

 (def pages
   {:home  plot
    :about about-page})
-
-

 (defn page []


Tagging screenshots on intro page with version

This will make it easy to track indirectly which version is being
installed.

--- src/ui/relevance/display.cljs
+++ src/ui/relevance/display.cljs
@@ -216,7 +216,7 @@
     [:p "I'm a tab-aholic. I normally do a search, start opening the tabs that seem interesting, and then as I flip through them, I end up opening even more links on tabs as they seem relevant."]
     [:p "Next thing I know I have a huge mess of tabs, and it's hard to remember which one I've read, or which one is more relevant."]
     [:p "I wrote Relevance to help manage that."]
-    [:p "When you install Relevance, it'll keep track of the pages you actually read, and how long you spend reading them. This information is kept completely private, on your local browser. As you open tabs, its knowledge of what's important to you grows, and when you activate it by pressing the button, the tabs  for your current window are ordered depending on how long you have spent reading them."]
+    [:p "When you install Relevance, it'll keep track of the pages you actually read, and how long you spend reading them. This information is kept completely private, on your local browser. As you open tabs, its knowledge of what's important to you grows, and when you activate it, the tabs  for your current window are ordered depending on how long you have spent reading them."]
     [:p "This ordering creates a natural arrangement where the tabs you have spent the longest on, which are expected to be the most relevant, are placed first, and the ones you haven't read at all are shunted to the end."]
     [:p "I've found this very useful in organizing what I should be focusing on."]]
    [:div {:class "col-sm-10 col-sm-offset-1"}
@@ -239,13 +239,13 @@
      [:div {:class "col-sm-12"}
       [:strong "Before"]]
      [:div {:class "col-sm-12"}
-      [:img {:src "http://numergent.com/images/relevance/relevance-clojure chrome before.png"}]]
+      [:img {:src "http://numergent.com/images/relevance/relevance-0.3-clojure chrome before.png"}]]
      ]
     [:div {:class "col-sm-6"}
      [:div {:class "col-sm-12"}
       [:strong "After"]]
      [:div {:class "col-sm-12"}
-      [:img {:src "http://numergent.com/images/relevance/relevance-clojure chrome after.png"}]]
+      [:img {:src "http://numergent.com/images/relevance/relevance-0.3-clojure chrome after.png"}]]
      ]]
    ]
   )


Fix project ordering

Fix project ordering

--- src/uxbox/data/dashboard.cljs
+++ src/uxbox/data/dashboard.cljs
@@ -67,7 +67,7 @@
   (reify
     rs/UpdateEvent
     (-apply-update [_ state]
-      (assoc-in state [:dashboard :project-ordering] order))
+      (assoc-in state [:dashboard :project-order] order))

     IPrintWithWriter
     (-pr-writer [mv writer _]


Fixed whitespace

Fixed whitespace

--- src/aero/core.clj
+++ src/aero/core.clj
@@ -165,18 +165,22 @@

 (defrecord TagWrapper
   [tag value])
+
 (defn- tag-wrapper
   "Call from :default of clojure.edn to wrap all tags it encounters & cannot handle itself.
    TODO: Anything special needed to support a mirror of dynamic var related to *tags*?"
   [tag value]
   (->TagWrapper tag value))
+
 (defn- tag-wrapper?
   [x]
   (= (type x) TagWrapper))
+
 (defn- tag-wrapper-of?
   [x tag]
   (and (tag-wrapper? x)
        (= (:tag x) tag)))
+
 (defn- tag-wrapper-of-ref?
   [x]
   (tag-wrapper-of? x 'ref))
@@ -219,6 +223,7 @@
          kvs)
        [pk x])
      [[pk x]])))
+
 (defn shorter-variations
   "Given a sequence '(1 2 3) return a sequence of all shorter
   possible sequences: '((1 2) (1))"
@@ -229,9 +234,11 @@
       (recur (conj r ys)
              (butlast ys))
       r)))
+
 (defn ref-dependency
   [ref*]
   (:value ref*))
+
 (defn ref-dependencies
   "Recursively checks a ref for nested dependencies"
   [ref*]
@@ -245,6 +252,7 @@
         (concat nested-deps
                 (->> nested-deps
                      (mapcat ref-dependencies)))))))
+
 (defn config->ref-graph
   [config]
   (reduce
@@ -256,6 +264,7 @@
     (filter
       (comp tag-wrapper-of-ref? second)
       (pathify conj [] config))))
+
 (defn resolve-refs
   "Resolves refs & any necessary tags in order to do it's job"
   [config resolve-fn]
@@ -299,6 +308,7 @@
       (catch Exception e
         (let [line (.getLineNumber pr)]
           (throw (ex-info (format "Config error on line %s" line) {:line line} e)))))))
+
 (defn read-config
   "Optional second argument is a map that can include the following keys:
   :profile - indicates the profile to use for #profile extension


check filter expressions

check filter expressions

--- ssclj/jar/src/test/clojure/com/sixsq/slipstream/ssclj/filter/parser_test.clj
+++ ssclj/jar/src/test/clojure/com/sixsq/slipstream/ssclj/filter/parser_test.clj
@@ -25,7 +25,9 @@
   (expect passes "\"a1\"")
   (expect passes "\"\\\"a\"")
   (expect passes "\"a\\\"\"")
-  (expect passes "\"a\\\"a\""))
+  (expect passes "\"a\\\"a\"")
+  (expect passes "\"b0\"")
+  (expect passes "\"b-0\""))

 ;; valid single quoted strings
 (let [passes (passes-fn :SingleQuoteString)]
@@ -34,7 +36,9 @@
   (expect passes "'a1'")
   (expect passes "'\\'a'")
   (expect passes "'a\\''")
-  (expect passes "'a\\'a'"))
+  (expect passes "'a\\'a'")
+  (expect passes "'b0'")
+  (expect passes "'b-0'"))

 ;; valid dates
 (let [passes (passes-fn :DateValue)]
@@ -69,7 +73,11 @@
   (expect passes "alpha=3 and beta=4")
   (expect passes "alpha=3 or beta=4")
   (expect passes "alpha=3 and beta=4 or gamma=5 and delta=6")
-  (expect passes "alpha=3 and (beta=4 or gamma=5) and delta=6"))
+  (expect passes "alpha=3 and (beta=4 or gamma=5) and delta=6")
+  (expect passes "b='b0'")
+  (expect passes "b='b-0'")
+  (expect passes "'b0'=b")
+  (expect passes "'b-0'=b"))

 ;; invalid filters
 (let [fails (fails-fn :Filter)]


Fixed some bad unused variables and other bugs

--- src/cine/core.clj
+++ src/cine/core.clj
@@ -4,13 +4,14 @@
             [cine.utils :refer [month-to-num]])
   (:gen-class))

+(defn fetch-url [url]
+  (enlive/html-resource (java.net.URL. url)))
+
 (def cinehub-url "http://w3.cineplexbd.com/~ab46419/cineplexbd/index.php")
 (def schedule-url "http://w3.cineplexbd.com/~ab46419/cineplexbd/index.php?visit=schedule/schedules&a=1")
 (def movie-list-markup (fetch-url cinehub-url))
 (def schedule-markup (fetch-url schedule-url))

-(defn fetch-url [url]
-  (enlive/html-resource (java.net.URL. url)))

 (defn get-current-movies
   "Returns a list of movies that are being aired now"
@@ -90,10 +91,9 @@
         date-str (str (:date date-map) "/" (:month date-map) "/" (:year date-map))
         mov-schedule (make-single-movie-schedule-wo-date single-schedule-markup)]
     (map #(assoc % :date date-str) mov-schedule)))
-(make-single-movie-schedule one)

-(map make-single-movie-schedule schedules-root-divs)
-
+(defn get-weekly-movie-schedule []
+  (map make-single-movie-schedule schedules-root-divs))

 (defn -main
   "I don't do a whole lot ... yet."


Link "Builds" and "Insights"

Link "Builds" and "Insights"

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -549,7 +549,11 @@
          [:span.big-number "2"]
          [:div.instruction
           [:p "Choose a repo to add to CircleCI. We'll start a new build for you each time someone pushes a new commit."]
-          [:p "You can also follow a repo that's already been added to CircleCI. You'll see your followed projects in Builds and Insights."]]]
+          [:p "You can also follow a repo that's already been added to CircleCI. You'll see your followed projects in "
+           [:a {:href (routes/v1-dashboard-path {})} "Builds"]
+           " and "
+           [:a {:href (routes/v1-insights)} "Insights"]
+           "."]]]
          (om/build repo-lists {:user user
                                :repos repos
                                :selected-org selected-org


fix the attribute name

fix the attribute name

--- src-cljs/frontend/components/integrations.cljs
+++ src-cljs/frontend/components/integrations.cljs
@@ -130,13 +130,13 @@
     om/IDidMount
     (did-mount [_]
       (fdb/add-attribute-listener (om/get-shared owner :team-db)
-                                  :slack/channel-name
+                                  :slack-hook/channel-name
                                   (om/get-shared owner :listener-key)
                                   #(om/refresh! owner)))
     om/IWillUnmount
     (will-unmount [_]
       (fdb/remove-attribute-listener (om/get-shared owner :team-db)
-                                     :slack/channel-name
+                                     :slack-hook/channel-name
                                      (om/get-shared owner :listener-key)))
     om/IRender
     (render [_]


better validation in edn read-map

better validation in edn read-map

--- src/main/cljs/cljs/tools/reader/edn.cljs
+++ src/main/cljs/cljs/tools/reader/edn.cljs
@@ -192,11 +192,27 @@
   [rdr _ opts]
   (read-delimited \] rdr opts))

+(defn- duplicate-keys-error [msg coll]
+  (letfn [(duplicates [seq]
+            (for [[id freq] (frequencies seq)
+                  :when (> freq 1)]
+              id))]
+    (let [dups (duplicates coll)]
+      (apply str msg
+             (when (> (count dups) 1) "s")
+             ": " (interpose ", " dups)))))
+
 (defn- read-map
   [rdr _ opts]
-  (let [l (to-array (read-delimited \} rdr opts))]
+  (let [the-map (read-delimited \} rdr opts)
+        ks (take-nth 2 the-map)
+        key-set (set ks)
+        l (to-array the-map)]
     (when (== 1 (bit-and (alength l) 1))
       (reader-error rdr "Map literal must contain an even number of forms"))
+    (when-not (= (count key-set) (count ks))
+      (reader-error rdr (duplicate-keys-error
+                         "Map literal contains duplicate key" ks)))
     (apply hash-map l)))

 (defn- read-number


for phrasal complements, calling assoc-in to add them to the parent bolt

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -169,14 +169,17 @@
                                           "; top-bolt:"
                                           ((:morph-ps model) top-bolt)))
                           (if (= false (get-in bolt-at [:phrasal]))
-                            (do
+                            (let [result
+                                  [(assoc-in bolt path bolt-at)]]
                               (log/debug (str "(assoc-in (lexical) " ((:morph-ps model) bolt) " " path " "
-                                              ((:morph-ps model) bolt-at)))
-                              [(assoc-in bolt path bolt-at)])
-                            (let [comps-map (comp-paths-to-bolts-map bolt-at model (+ 1 depth) max-depth)
-                                  comp-paths (sort (keys comps-map))]
+                                              ((:morph-ps model) bolt-at) " => "
+                                              (string/join "," (map #((:morph-ps model) %)
+                                                                    result))))
+                              result)
+                            (let [comps-map (comp-paths-to-bolts-map bolt-at model (+ 1 depth) max-depth)]
                               (when (not (some empty? (vals comps-map)))
-                                (let [result
+                                (let [comp-paths (sort (keys comps-map))
+                                      result
                                       (add-comps bolt-at
                                                  model
                                                  comp-paths
@@ -190,7 +193,8 @@
                                                       path))]
                                   (log/debug (str "(assoc-in (phrasal) " ((:morph-ps model) bolt) " " path " "
                                                   ((:morph-ps model) bolt-at)))
-                                  result)))))
+                                  (map #(assoc-in bolt path %)
+                                       result))))))
                         bolts-at))))))
 (defn generate2
   "Return all expressions matching spec _spec_ given the model _model_."


small speed improvement: don't copy candidate lexemes if we don't need to

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -254,7 +254,7 @@
                          (if (= false (get-in parent [:head :phrasal] false))
                            (let [candidate-lexemes (get-lex parent :head index spec)]
                              (filter #(not (nil? %))
-                                     (over/overh parent (mapfn copy (shuffle candidate-lexemes)))))))
+                                     (over/overh parent (shuffle candidate-lexemes))))))
                        parents)
           phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.
           (if (and (< total-depth max-total-depth)


~(defn parent-with-head): add missing bracket; more simplification

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -120,16 +120,14 @@

 (defn parent-with-head
   "Return every possible tree of depth 1 from the given spec."
-  [spec depth
+  [spec depth]
   ;; get all rules that match input _spec_:
-   (->> grammar
-        (map #(unify % spec))
-        (filter #(not (= :fail %)))
-
-        ;; try to add heads to each matching rule:
-        (parent-with-head-1 spec depth)
-        (filter #(not (= % :fail)))
-        (map #(u/assoc-in! % [::started?] true)))])
+  (->> grammar
+       (map #(unify % spec))
+       (remove #(= :fail %))
+       (parent-with-head-1 spec depth)
+       (remove #(= % :fail))
+       (map #(u/assoc-in! % [::started?] true))))

 (defn parent-with-head-1 [spec depth parent-rules]
   (if (not (empty? parent-rules))


logging improvements

logging improvements

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -243,7 +243,7 @@
     result))

 (defn add-complement [bolt path spec grammar lexicon cache morph depth total-depth]
-  (log/debug (str "add-complement: start: " (show-bolt bolt path morph)))
+  (log/debug (str "add-complement: start: " (show-bolt bolt path morph) "@" path))
   (let [input-spec spec
         from-bolt bolt ;; so we can show what (add-complement) did to the input bolt, for logging.
         spec (unifyc spec (get-in bolt path))


Add docstring.

Add docstring.

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -607,6 +607,7 @@
 (defsodium)

 (defn load-sodium
+  "Load native libsodium library."
   ([]
    (load-sodium "sodium"))
   ([lib]


[CORE]

[CORE]

--- src/clj/aliyun/core.clj
+++ src/clj/aliyun/core.clj
@@ -19,7 +19,8 @@
 (defn mk-acs-client
   [region access-key secret-key]
     (let [^DefaultProfile profile (mk-acs-profile region access-key secret-key)
-          ^DefaultAcsClient client (DefaultAcsClient. profile)]))
+          ^DefaultAcsClient client (DefaultAcsClient. profile)]
+    client))

 (defn get-response
   [^DefaultAcsClient client request]


Handle missing nodes more gracefully

Handle missing nodes more gracefully

--- src/clj/shale/nodes.clj
+++ src/clj/shale/nodes.clj
@@ -75,11 +75,11 @@
        (merge {:id id})
        keywordize-keys))

-(s/defn view-model :- NodeView
+(s/defn view-model :- (s/maybe NodeView)
   "Given a node pool, get a view model from Redis."
   [pool :- NodePool
    id   :- s/Str]
-  (let [m (redis/model (:redis-conn pool) redis/NodeInRedis id)]
+  (when-let [m (redis/model (:redis-conn pool) redis/NodeInRedis id)]
     (->NodeView id m)))

 (s/defn view-models :- [NodeView]


Add lower-bounds check to Vector nth. Refs #1

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -918,13 +918,12 @@
   (-count [coll] (.length array))

   IIndexed
-  ; Must also check lower bound, (<= 0 n)
   (-nth [coll n]
-    (if (< n (.length array))
+    (if (and (<= 0 n) (< n (.length array)))
       (aget array n)
       #_(throw (str "No item " n " in vector of length " (.length array)))))
   (-nth [coll n not-found]
-    (if (< n (.length array))
+    (if (and (<= 0 n) (< n (.length array)))
       (aget array n)
       not-found))


CLJS-232: remove (extend-type default IReduce ...)

This commit removes the default implementation of IReduce and patches
cljs.core/reduce to check if its collection argument implements
IReduce before delegating to -reduce.

For non-implementing collection types, the private helper function
seq-reduce is now called which rolls over to -reduce as soon as
possible.

A new predicate cljs.core/reducible? is also introduced.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -750,6 +750,10 @@
   "Returns true if coll implements nth in constant time"
   [x] (satisfies? IIndexed x))

+(defn ^boolean reducible?
+  "Returns true if coll satisfies IReduce"
+  [x] (satisfies? IReduce x))
+
 (defn ^boolean map?
   "Return true if x satisfies IMap"
   [x]
@@ -943,31 +947,6 @@
   ([keyfn comp coll]
      (sort (fn [x y] ((fn->comparator comp) (keyfn x) (keyfn y))) coll)))

-(defn reduce
-  "f should be a function of 2 arguments. If val is not supplied,
-  returns the result of applying f to the first 2 items in coll, then
-  applying f to that result and the 3rd item, etc. If coll contains no
-  items, f must accept no arguments as well, and reduce returns the
-  result of calling f with no arguments.  If coll has only 1 item, it
-  is returned and f is not called.  If val is supplied, returns the
-  result of applying f to val and the first item in coll, then
-  applying f to that result and the 2nd item, etc. If coll contains no
-  items, returns val and f is not called."
-  ([f coll]
-     (-reduce coll f))
-  ([f val coll]
-     (-reduce coll f val)))
-
-(defn reduce-kv
-  "Reduces an associative collection. f should be a function of 3
-  arguments. Returns the result of applying f to init, the first key
-  and the first value in coll, then applying f to that result and the
-  2nd key and value, etc. If coll contains no entries, returns init
-  and f is not called. Note that reduce-kv is supported on vectors,
-  where the keys will be the ordinals."
-  ([f init coll]
-     (-kv-reduce coll f init)))
-
 ; simple reduce based on seqs, used as default
 (defn- seq-reduce
   ([f coll]
@@ -983,13 +962,34 @@
             (recur nval (next coll))))
         val))))

-(extend-type default
-  IReduce
-  (-reduce
-    ([coll f]
-       (seq-reduce f coll))
-    ([coll f start]
-       (seq-reduce f start coll))))
+(defn reduce
+  "f should be a function of 2 arguments. If val is not supplied,
+  returns the result of applying f to the first 2 items in coll, then
+  applying f to that result and the 3rd item, etc. If coll contains no
+  items, f must accept no arguments as well, and reduce returns the
+  result of calling f with no arguments.  If coll has only 1 item, it
+  is returned and f is not called.  If val is supplied, returns the
+  result of applying f to val and the first item in coll, then
+  applying f to that result and the 2nd item, etc. If coll contains no
+  items, returns val and f is not called."
+  ([f coll]
+     (if (reducible? coll)
+       (-reduce coll f)
+       (seq-reduce f coll)))
+  ([f val coll]
+     (if (reducible? coll)
+       (-reduce coll f val)
+       (seq-reduce f val coll))))
+
+(defn reduce-kv
+  "Reduces an associative collection. f should be a function of 3
+  arguments. Returns the result of applying f to init, the first key
+  and the first value in coll, then applying f to that result and the
+  2nd key and value, etc. If coll contains no entries, returns init
+  and f is not called. Note that reduce-kv is supported on vectors,
+  where the keys will be the ordinals."
+  ([f init coll]
+     (-kv-reduce coll f init)))

 (deftype Reduced [val]
   IDeref


Remove lein daemon, no longer necessary

Remove lein daemon, no longer necessary

--- backend/project.clj
+++ backend/project.clj
@@ -73,7 +73,6 @@
                  [org.cloudhoist/java "0.5.1"]
                  [org.cloudhoist/nginx "f48febc9e5e43148719a11c3aeca4e6b668993e"]
                  [lein-crate "0.1.0"]
-                 [lein-daemon "0.4.2"]
                  [pallet-rvm "0.1"]
                  [cdt "1.2.6.1-SNAPSHOT"]]

@@ -82,7 +81,6 @@
   :dev-dependencies [[lein-test-out "0.1.1"]
                      [midje "1.2.0"]
                      [lein-midje "1.0.4"]
-                     [lein-daemon "0.4.2"]
                      [clojure-source "1.2.1"]]
   :main ^{:skip-aot true} circle.init ;; careful https://github.com/marick/Midje/issues/12
   :jvm-opts ~jvm-opts)


[#241] Removed unused libs (#243)

[#241] Removed unused libs (#243)

--- backend/project.clj
+++ backend/project.clj
@@ -8,7 +8,6 @@
                  [clj-http "2.1.0"]
                  [clj-time "0.11.0"]
                  [com.layerware/hugsql "0.4.6"]
-                 [com.novemberain/pantomime "2.8.0"]
                  [com.stuartsierra/component "0.3.1"]
                  [compojure "1.5.0"]
                  [duct "0.5.10"]
@@ -26,7 +25,6 @@
                  [org.immutant/web "2.1.3"]
                  [org.postgresql/postgresql "9.4.1208"]
                  [org.slf4j/slf4j-nop "1.7.19"]
-                 [pandect "0.5.4"]
                  [ragtime "0.5.3"]
                  [ring "1.4.0"]
                  [ring/ring-defaults "0.2.0"]


wrote syntax validation. phenomenal

wrote syntax validation. phenomenal

--- src/kvdb/core.clj
+++ src/kvdb/core.clj
@@ -5,11 +5,10 @@
 ;; TODO
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-;; Catch errors in kv_parse
-;; Hashmap functions https://redis.io/commands#hash
-;; Set functions https://redis.io/commands#set
-;; Metadata for naming databases
+;; Catch errors in kv-parse
 ;; Do values have to be returned with every command?
+;; Multimethod to validate syntax
+;; ;; Dispatch on first argument!

 ;; LATER TODO
 ;; Add radix tree?
@@ -32,7 +31,7 @@

 (defn kv-whole-map
   "Returns a hashmap snapshot of the entire database
-  {k [type value] ...}"
+  {k [type value]}"
   [db]
   (into {}
     (map
@@ -179,6 +178,50 @@
   (kv-run db (clojure.string/split string #" ")))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; SYNTAX
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defmulti validate
+  "Validates syntax"
+  (fn [string] (first (clojure.string/split string #" "))))
+
+(defmethod validate "ASYNC"
+  [string]
+  (->> string (#(clojure.string/split % #" ")) rest (clojure.string/join " ") validate))
+
+(defmacro check-arity
+  [command argc]
+  (let [string (gensym)]
+    `(defmethod validate ~command
+      [~string]
+      (= (- ~argc 1) (->> ~string (#(clojure.string/split % #" ")) count)))))
+
+(defmacro check-min-arity
+  [command argc]
+  (let [string (gensym)]
+    `(defmethod validate ~command
+      [~string]
+      (< ~argc (->> ~string (#(clojure.string/split % #" ")) count)))))
+
+(defmacro check-pairs
+  [command argc]
+  (let [string (gensym)]
+    `(defmethod validate ~command
+      [~string]
+      (< ~argc (->> ~string (#(clojure.string/split % #" ")) count)))))
+
+(check-arity "GET" 1)
+(check-arity "SET" 2)
+(check-arity "HGET" 2)
+(check-min-arity "DEL" 1)
+(check-min-arity "HDEL" 2)
+(check-min-arity "EXISTS" 1)
+
+(defmethod validate "HSET"
+  [string]
+  (let [argc (->> string (#(clojure.string/split % #" ")) count)]
+    (and (> argc 2) (= (mod argc 2) 0))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; TESTING
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@@ -188,7 +231,7 @@
   [db]
   (kv-parse db "SET x 4")
   (println "x SET to 4")
-  (future (swap! db (fn [x] (Thread/sleep 10000) (println "Delay ended") (assoc x "y" (atom "4")))))
+  (future (swap! db (fn [x] (Thread/sleep 10000) (println "Delay ended") (assoc x "y" [:raw (atom "4")]))))
   (println "Delay started")
   (kv-parse db "SET x 5")
   (println (kv-parse db "GET x")))


Implemented removal of menus

Implemented removal of menus

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

--- src/conexp/gui/util.clj
+++ src/conexp/gui/util.clj
@@ -102,18 +102,30 @@
   "Adds the additional menus to the frame in front of the first Box.Filler
   found in the menu-bar of frame."
   [frame menus]
+  (let [our-menus (map #(hash-map->menu frame %) menus)]
+    (do-swing-and-wait
+     (let [menu-bar (get-menubar frame)
+	   [menus-before menus-after] (split-with #(not (instance? javax.swing.Box$Filler %))
+						  (seq (.getComponents menu-bar)))]
+       (.removeAll menu-bar)
+       (doseq [menu (concat menus-before our-menus menus-after)]
+	 (.add menu-bar menu))
+       (.validate frame)))
+    our-menus))
+
+(defn remove-menus
+  "Removes given menus from menu-bar of frame."
+  [frame menus]
   (do-swing-and-wait
-   (let [menu-bar (get-menubar frame)
-	 [menus-before menus-after] (split-with #(not (instance? javax.swing.Box$Filler %))
-						(seq (.getComponents menu-bar))),
-	 our-menus (map #(hash-map->menu frame %) menus)]
+   (let [menu-bar (get-menubar frame),
+	 new-menus (remove (set menus) (seq (.getComponents menu-bar)))]
      (.removeAll menu-bar)
-     (doseq [menu (concat menus-before our-menus menus-after)]
+     (doseq [menu new-menus]
        (.add menu-bar menu))
      (.validate frame)
-     our-menus)))
-
-;; shortcut variables for convenience
+     new-menus)))
+
+;; menu shortcut variables for convenience

 (defvar --- {}
   "Separator for menu entries used in add-menus.")


fix wrong logic

fix wrong logic

--- src/neuseg/db.clj
+++ src/neuseg/db.clj
@@ -10,19 +10,14 @@
     "trigram"   (atom {})
     "quadgram"  (atom {}) })

-(defn- enum-splited-line [data line]
-  (let [[idx _ _] data
-        items (clojure.string/split line #"\s+")
+(defn- splited-line [line]
+  (let [items (clojure.string/split line #"\s+")
         wd    (first items)
         nvec  (normalise (vec (map #(Double. %1) (rest items))))]
-    (if-not idx
-      (tuple -1 nil nil)
-      (do
-        (if (= (mod idx 1000) 0) (println idx))
-        (tuple (+ idx 1) wd nvec)))))
+        (tuple wd nvec)))

 (defn- reg-wd-neglect [name data]
-  (let [[idx wd nvec] data]
+  (let [[[wd nvec] idx] data]
     (if (> idx -1)
       (do
         (swap! assoc (get registry name) wd idx)
@@ -31,7 +26,7 @@
 (defn load-db [name]
   (with-open [rdr (clojure.java.io/reader (str "data" "/" name))]
     (map (partial reg-wd-neglect name)
-         (reduce enum-splited-line [] (rest (line-seq rdr))))))
+         (partition 2 (interleave (map splited-line (rest (line-seq rdr))) (iterate inc 1)))))

 (def unigram  (matrix (load-db "unigram")))
 (def bigram   (matrix (load-db "bigram")))


extract helper

extract helper

--- src/osmium/db.clj
+++ src/osmium/db.clj
@@ -25,3 +25,6 @@
   ([] (new-datomic-db "datomic:mem://localhost:4334/osmium"))
   ([uri]
    (map->Datomic {:uri uri})))
+
+(defn ->map [e]
+  (into {:db/id (:db/id e)} e))


Adjusts example.

Adjusts example.

--- src/active/clojure/match.clj
+++ src/active/clojure/match.clj
@@ -1010,15 +1010,16 @@
              (:y \"y\")
              (:z :as z)
              :w]
-            (println x y z w)
+            (println x z)
             [(:a \"a\" :as a)
              (:b \"b\")
              (:c :as c)
+             ([:d] :as d)
              ([:d Z] 42 :as Z)
              ([:d Y] :as Y)
              ([:d X] 65)
              [:d W foo]]
-            (println a b c Z Y X foo)
+            (println a c d Z Y)
             :else false))

         (example-map-matcher {:a \"a\" :b \"b\" :c \"c\"
@@ -1026,8 +1027,7 @@
                                   \"W\" {\"foo\" \"bar\"}}})

     prints
-
-     \"a b c d 42 23 65 bar\""
+     \"a c {\"Z\" 42 \"Y\" 23 \"X\" 65 \"W\" {\"foo\" \"bar\"}}  42 23\""
   [& args]
   (when-not (even? (count args))
     (throw (IllegalArgumentException. (str "expecting an even number of arguments " *ns* " " (meta &form)))))


Added tests for casting helpers

Added tests for casting helpers

--- test/semantic_csv/core_test.clj
+++ test/semantic_csv/core_test.clj
@@ -79,3 +79,20 @@
              {:this "1" :that 2})))))

+(deftest casting-function-helpers-test
+  (testing "with string inputs"
+    (let [n "3443"
+          x "4.555"]
+      (is (= (->int n) 3443))
+      (is (= (->long n) 3443))
+      (is (= (->float x) 4.555))
+      (is (= (->double x) 4.555))))
+  (testing "with numeric inputs"
+    (for [x [3443 4.555]
+          f [->float ->double]]
+      (is (= (f x) (double x))))
+    (for [x [3443 4.555]
+          f [->int ->long]]
+      (is (= (f x) (long x))))))
+
+


feat(model.db): introduce find-by-predicate

--- src/busa_server/model/db.clj
+++ src/busa_server/model/db.clj
@@ -77,3 +77,10 @@
     (r/table table)
     (r/delete)
     (r/run @current-db-connection)))
+
+(defn find-by-predicate [table predicate]
+  (->
+    (r/db @current-db)
+    (r/table table)
+    (r/filter predicate)
+    (r/run @current-db-connection)))


Removed unused http namespace

Removed unused http namespace

--- src/clj/clojuredocs/http.clj
+++ src/clj/clojuredocs/http.clj
@@ -1,5 +0,0 @@
-(ns clojuredocs.http)
-
-(defn html-resp [body]
-  {:headers {"Content-Type" "text/html;charset=utf-8"}
-   :body body})


add more logging

add more logging

--- src/clj/hsm/system/kafka.clj
+++ src/clj/hsm/system/kafka.clj
@@ -24,6 +24,7 @@

   (start [component]
     (try
+      (log/warn "Starting KAFKA PROD Component")
       (let [producing-channel (or prod-chan (chan))
             brokers (get-broker-list zookeeper)
             producer-config {"metadata.broker.list" brokers
@@ -34,7 +35,9 @@
           (let [[[topic msg] ch] (alts! [producing-channel])]
             (send! producer topic msg))))
          (assoc component :channel producing-channel))
-      (catch Throwable t (log/error t))))
+      (catch Throwable t
+        (do (log/warn "[KAFKA-PROD] FAILED")
+        (log/error t)))))
   (stop [component]

     )


nil check

nil check

--- src/cljc/swarmpit/utils.cljc
+++ src/cljc/swarmpit/utils.cljc
@@ -73,8 +73,8 @@

 (defn ->nano
   [number]
-  (* number 1000000000))
+  (when number (* number 1000000000)))

 (defn nano->
   [number]
-  (/ number 1000000000))+  (when number (/ number 1000000000)))


simplify algorithm

simplify algorithm

--- src/cljs/triboard/ai/ai.cljs
+++ src/cljs/triboard/ai/ai.cljs
@@ -28,9 +28,9 @@
 (defn- compute-cells-strength
   "Adds to a given turn the strength of each of its cells"
   [board]
-  (reduce
-    #(assoc %1 %2 (compute-cell-strength board %2))
-    {} cst/all-positions))
+  (into {}
+    (map (fn [point] [point (compute-cell-strength board point)]))
+    cst/all-positions))

 (defn- move-strength
   "Compute the strength of a move, based on the converted cells"


Add docstrings.

Add docstrings.

--- src/cljs_bach/synthesis.cljs
+++ src/cljs_bach/synthesis.cljs
@@ -35,7 +35,9 @@
   [synth context at duration]
   (synth context at duration))

-(defn destination [context at duration]
+(defn destination
+  "The destination of the audio context i.e. the speakers."
+  [context at duration]
   (sink (.-destination context)))

 (defn plug [param input context at duration]
@@ -44,13 +46,17 @@
     (.setValueAtTime param input at)
     (-> input (run-with context at duration) :output (.connect param))))

-(defn gain [level]
+(defn gain
+  "Multiply the signal by level."
+  [level]
   (fn [context at duration]
     (subgraph
       (doto (.createGain context)
         (-> .-gain (plug level context at duration))))))

-(def pass-through (gain 1.0))
+(def pass-through
+  "Pass the signal through unaltered."
+  (gain 1.0))

 ; Envelopes
@@ -69,17 +75,23 @@
         corners)
       (subgraph audio-node))))

-(defn adshr [attack decay sustain hold release]
+(defn adshr
+  "An ADSR envelope that also lets you specify the hold duration."
+  [attack decay sustain hold release]
   (envelope [attack 1.0] [decay sustain] [hold sustain] [release 0]))

-(defn adsr [attack decay sustain release]
+(defn adsr
+  "A four-stage envelope."
+  [attack decay sustain release]
   (fn [context at duration]
     (let [remainder (- duration attack decay sustain)
           hold (max 0.0 remainder)
           node (adshr attack decay sustain hold release)]
       (-> node (run-with context at duration)))))

-(defn percussive [attack decay]
+(defn percussive
+  "A simple envelope."
+  [attack decay]
   (envelope [attack 1.0] [decay 0.0]))

@@ -144,6 +156,7 @@
         (.start at)))))

 (def white-noise
+  "Random noise."
   (let [white (fn [_] (-> (js/Math.random) (* 2.0) (- 1.0)))]
     (noise white)))

@@ -155,6 +168,7 @@
 ; Oscillators

 (defn oscillator
+  "A periodic wave."
   [type freq]
   (fn [context at duration]
     (source
@@ -174,6 +188,7 @@
 ; Filters

 (defn biquad-filter
+  "Attenuate frequencies beyond the cutoff, and intensify the cutoff frequency based on the value of q."
   ([type freq]
    (biquad-filter type freq 1.0))
   ([type freq q]
@@ -191,13 +206,16 @@

 ; Effects

-(defn stereo-panner [pan]
+(defn stereo-panner
+  "Pan the signal left (-1) or right (1)."
+  [pan]
   (fn [context at duration]
     (subgraph
       (doto (.createStereoPanner context)
         (-> .-pan (plug pan context at duration))))))

 (defn delay-line
+  "Delay the signal."
   [seconds]
   (fn [context at duration]
     (subgraph
@@ -206,6 +224,7 @@
           (-> .-delayTime (plug seconds context at duration)))))))

 (defn convolver
+  "Linear convolution."
   [generate-bit!]
   (fn [context at duration]
     (subgraph
@@ -213,6 +232,7 @@
         (-> .-buffer (set! (buffer generate-bit! context (+ duration 1.0))))))))

 (def reverb
+  "Crude reverb."
   (let [duration 5
         decay 3
         sample-rate 44100


Rewrite number instance not-equal in terms of equal

--- src/clojure_ruby/corelib.clj
+++ src/clojure_ruby/corelib.clj
@@ -35,8 +35,8 @@
     (create-boolean (= (:data this) other))))

 (defn number-not-equal [this other]
-  (let [other (msg/host other :number)]
-    (create-boolean (not= (:data this) other))))
+  (let [eq (msg/ruby this "==" [other])]
+    (create-boolean (not (msg/host eq :boolean)))))

 (defn number-host-number [this]
   (:data this))


CORS options route for /queries/cypher

CORS options route for /queries/cypher

--- src/cmr/graph/rest/route.clj
+++ src/cmr/graph/rest/route.clj
@@ -87,9 +87,10 @@
 (defn dangerous
   [httpd-component]
   (let [conn (neo4j/get-conn httpd-component)]
-    [["/queries/cypher" {
-      :get (handler/cypher-injection-get conn)
-      :post (handler/cypher-injection-post conn)}]]))
+    [["/queries/cypher"
+      {:get (handler/cypher-injection-get conn)
+       :post (handler/cypher-injection-post conn)
+       :options handler/ok}]]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;   Utility Routes   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


implement get-permissions for posix filesystem

--- src/com/brainbot/real_fs.clj
+++ src/com/brainbot/real_fs.clj
@@ -53,12 +53,15 @@
   (let [perm (.permissions attr)
         owner-name (str "USER:" (.getName (.owner attr)))
         group-name (str "GROUP:" (.getName (.group attr)))]
-    (acl-from-posix-perm owner-name group-name "GROUP:AUTHENTICATED_USERS")))
+    (acl-from-posix-perm owner-name group-name "GROUP:AUTHENTICATED_USERS" perm)))

 (defrecord RealFilesystem [root]
   vfs/Filesystem
-  ;; (get-permissions [fs entry] ...)
+  (get-permissions [fs entry]
+    (let [fp (string/join "/" [(:root fs) entry])
+          attr (read-attributes fp)]
+      (acl-from-attribute attr)))

   (stat [fs entry]
     (let [fp (string/join "/" [(:root fs) entry])


Import less into core

Import less into core

--- src/commons/clojure/core.clj
+++ src/commons/clojure/core.clj
@@ -10,13 +10,11 @@
 (immigrate/selection 'slingshot.slingshot '[try+ throw+])

 ;; Grab suchwow functions
-(immigrate/namespaces 'such.shorthand 'such.symbols
-                      'such.types 'such.vars 'such.versions
+(immigrate/namespaces 'such.shorthand 'such.types
                       ;; including the overriding namespaces
                       'such.better-doc 'such.wide-domains)

 ;; And selected local functions:
-;(immigrate/selection 'commons.control-flow '[pred-cond -<> -<>> -!> -!>> -!<> some-<> some-<>>])
 (immigrate/namespaces 'commons.control-flow)
 (immigrate/namespaces 'commons.clojure.backwards-compatibility
                       'commons.environment


Fix stats

Fix stats

--- src/cyanite_remover/core.clj
+++ src/cyanite_remover/core.clj
@@ -11,6 +11,8 @@
 (def ^:const default-jobs 1)

 (def ^:const pbar-width 35)
+
+(def stats-processed (atom 0))

 (def list-metrics-str "Path: %s, rollup: %s, period: %s, time: %s, data: %s")
 (def starting-str "==================== Starting ====================")
@@ -103,7 +105,7 @@
         (when show-stats?
           (let [mstore-stats (mstore/get-stats mstore)
                 pstore-stats (pstore/get-stats pstore)]
-            (show-stats (:processed mstore-stats)
+            (show-stats @stats-processed
                         (+ (:errors mstore-stats)
                            (:errors pstore-stats)))))))))

@@ -118,6 +120,7 @@
 (defn- remove-metrics-path
   "List metrics for a path."
   [mstore options tenant rollup period path from to]
+  (swap! stats-processed inc)
   (let [times (get-times mstore options tenant rollup period path from to)]
     (wlog/info (str "Removing metrics: "
                     "rollup: " rollup ", "
@@ -176,6 +179,7 @@
     (dry-mode-warn options)
     (process-paths tenant paths es-url options
                    (fn [pstore options tenant paths]
+                     (swap! stats-processed inc)
                      (pstore/delete pstore tenant false false paths))
                    "Removing paths" true)
     (catch Exception e


Comment out subvis

Comment out subvis

--- src/day8/re_frame/trace.cljs
+++ src/day8/re_frame/trace.cljs
@@ -387,7 +387,7 @@
                                                       :on-click #(reset! selected-tab :traces)} "Traces"]
                                             [:button {:class (str "tab button " (when (= @selected-tab :app-state) "active"))
                                                       :on-click #(reset! selected-tab :app-state)} "app-state"]
-                                            [:button {:class (str "tab button " (when (= @selected-tab :subvis) "active"))
+                                            #_[:button {:class (str "tab button " (when (= @selected-tab :subvis) "active"))
                                                       :on-click #(reset! selected-tab :subvis)} "SubVis"]]]
                                         (case @selected-tab
                                           :traces [render-trace-panel]


Added the executable's path to the messages.

--- src/fm/simrunner/actions.clj
+++ src/fm/simrunner/actions.clj
@@ -102,12 +102,13 @@
                               (rdg/log-messages! app line)))))

 (defn- run-simulation [app widget]
-  (if-let [[_ config-file output-file :as args] (exec-args app)]
+  (if-let [[executable-file config-file output-file :as args] (exec-args app)]
     (do
       (rdg/log-messages! app
                          "Starting simulation run."
-                         (format "Config file: '%s'" config-file)
-                         (format "Ouput file : '%s'" output-file))
+                         (format "Executable file: '%s'" executable-file)
+                         (format "Config file    : '%s'" config-file)
+                         (format "Ouput file     : '%s'" output-file))
       (try
         (exc/wait-for (exc/drain-outputs (apply exc/exec args)
                                          :out> (console-logger app)


render deleted players and order matches

--- src/foosball/views/match.clj
+++ src/foosball/views/match.clj
@@ -69,16 +69,21 @@
      [:div.control-group.span4
       [:button.btn.btn-primary.btn-large.btn-block.span4 {:type "submit" :value "Report"} "Report Match Result"]]]]))

+(defn- render-player [playername]
+  (if playername
+    [:p playername]
+    [:p.text-error "Deleted"]))
+
 (defn- render-match [{:keys [matchdate team1 team2]}]
   (let [[t1p1 t1p2 t1score] (map team1 [:player1 :player2 :score])
         [t2p1 t2p2 t2score] (map team2 [:player1 :player2 :score])]
     [:tr
      [:td (format-time matchdate)]
-     [:td t1p1]
-     [:td t1p2]
+     [:td (render-player t1p1)]
+     [:td (render-player t1p2)]
      [:td t1score]
-     [:td t2p1]
-     [:td t2p2]
+     [:td (render-player t2p1)]
+     [:td (render-player t2p2)]
      [:td t2score]]))

 (defn table [matches]
@@ -98,7 +103,10 @@
       [:th "Player 2"]
       [:th "Score"]]]
     [:tbody
-     (map render-match matches)]]))
+     (->> matches
+          (sort-by :matchdate)
+          reverse
+          (map render-match))]]))

 (defn parse-form [p]
   {:matchdate       (-> p :matchdate parse-time)


Workaround for defmulti's defonce-y behavior

--- src/icecap/handlers/core.clj
+++ src/icecap/handlers/core.clj
@@ -3,7 +3,10 @@
   (:require [schema.core :as s]
             [clojure.core.async :as async :refer [go chan <! >!]]))

+(def get-schema nil) ;; anti-defonce behaavior of get-schema
 (defmulti get-schema identity)
+
+(def execute nil) ;; anti-defonce behaavior of get-schema
 (defmulti execute
   "Executes a plan.


110 in progress

110 in progress

--- stuf/src/sandbox/4clojure.clj
+++ stuf/src/sandbox/4clojure.clj
@@ -728,3 +728,7 @@
    (let [xss (mapcat #(vector (count %) (first %)) (partition-by identity xs))]
         (cons xss (f xss)))))

+;;110
+(defn f [p]
+  (as-> (map #(clojure.string/replace % #" " "") p) cp
+    (concat cp (apply map str cp))))


testing spec contents

testing spec contents

--- test/celestial/test/docker.clj
+++ test/celestial/test/docker.clj
@@ -11,5 +11,11 @@

 (with-conf
   (fact "basic creation"
-     (vconstruct redis-docker-spec) => (contains {})))
+    (let [{:keys [start-spec create-spec]} (vconstruct redis-docker-spec)]
+      start-spec =>
+         (contains {:binds ["/vagrant:/vagrant"]
+                    :port-bindings {"22/tcp" [{:host-ip "0.0.0.0" :host-port "2222"}]}})
+      create-spec =>
+         (contains {:image "narkisr:latest" :exposed-ports ["22/tcp"] :volumes ["/tmp"]})
+      )))


Useful Macro first of first column, close #78.

--- src/cljs/cljs_browser_repl/cljs_api/utils.cljs
+++ src/cljs/cljs_browser_repl/cljs_api/utils.cljs
@@ -7,7 +7,15 @@
 ;;; We can easily add or remove sections/topics and they will be automatically
 ;;; displayed in the API panel.
 (def custom-api-map
-  {:sections [(Section. "Datatypes" ""
+  {:sections [(Section. "Useful Macros" ""
+                        [(Topic. "conditionals"
+                                 '(if if-let cond condp and or when when-let))
+                         (Topic. "nesting, chaining, and interop"
+                                 '(-> ->> doto .. .))
+                         (Topic. "defining things"
+                                 '(def defn fn let binding defmulti defmethod
+                                    deftype defrecord reify this-as))])
+              (Section. "Datatypes" ""
                         [(Topic. "maps " '({:key1 val1 :key2 val2}))
                          (Topic. "vectors" '([1 2 3] [:a :b :c]))
                          (Topic. "sets" '(#{:a :b :c 1 2 3}))
@@ -22,14 +30,6 @@
                                  '("(fn |NAME| [<ARGS*>] |CONSTRAINTS| <ACTIONS*>)"))
                          (Topic. "anonymous inline funcion"
                                  '("#(<ACTION> |% %2 %3 OR %&|)"))])
-              (Section. "Useful Macros" ""
-                        [(Topic. "conditionals"
-                                 '(if if-let cond condp and or when when-let))
-                         (Topic. "nesting, chaining, and interop"
-                                 '(-> ->> doto .. .))
-                         (Topic. "defining things"
-                                 '(def defn fn let binding defmulti defmethod
-                                   deftype defrecord reify this-as))])
               (Section. "Useful Functions" ""
                         [(Topic. "math"
                                  '(+ - * / quot rem mod inc dec max min))


Correctly diff nested data structures While the current implementation of `fileset-diff` works well for diffing on scalar values, the semantics are not correct for diffing on nested structures. This small modification results in correct diffs.

--- boot/pod/src/boot/tmpdir.clj
+++ boot/pod/src/boot/tmpdir.clj
@@ -213,10 +213,11 @@
     (let [props   (or (seq props) [:id])
           d1      (diff-tree t1 props)
           d2      (diff-tree t2 props)
-          [x y _] (map (comp set keys) (data/diff d1 d2))]
-      {:added   (->> (set/difference   y x) (select-keys t2) (assoc after :tree))
-       :removed (->> (set/difference   x y) (select-keys t1) (assoc after :tree))
-       :changed (->> (set/intersection x y) (select-keys t2) (assoc after :tree))})))
+          [x y z] (map (comp set keys) (data/diff d1 d2))
+          changed-keys (set/union (set/intersection x y) (set/intersection (set/union x y) z))]
+      {:added   (->> (set/difference y x changed-keys) (select-keys t2) (assoc after :tree))
+       :removed (->> (set/difference x y changed-keys) (select-keys t1) (assoc after :tree))
+       :changed (->> changed-keys                      (select-keys t2) (assoc after :tree))})))

 (defn- fatal-conflict?
   [^File dest]


Add documentation for ring middlewares.

Add documentation for ring middlewares.

--- src/memoria/handlers/app.clj
+++ src/memoria/handlers/app.clj
@@ -7,14 +7,23 @@
             [memoria.db :as db]
             [memoria.handlers.cards :as cards-handler]))

-(defn wrap-request-logging [app]
+(defn wrap-request-logging
+  "Logs the data received in the request and the data generated in the response. Useful
+  for debugging."
+  [app]
   (fn [request]
     (timbre/info (str "Received request: " request))
     (let [response (app request)]
       (timbre/info (str "Response: " response "\n"))
       response)))

-(defn wrap-db-conn [app]
+(defn wrap-db-conn
+  "Gets a new connection from the database connection pool and binds that to the
+  memoria.db/*conn* dynamic var.
+
+  If the `memoria-mode` header is present in the request and its value is `test`,
+  then the test connection pool will be used. Otherwise, the default pool is used."
+  [app]
   (fn [request]
     (let [datasource (if (= "test" (get-in request [:headers "memoria-mode"]))
                        (db/test-datasource)


Port midje tests to clojure.test

Port midje tests to clojure.test

Made as few changes to pre-existing test layout as possible

--- test/hiccup_find/core_test.clj
+++ test/hiccup_find/core_test.clj
@@ -1,84 +1,92 @@
 (ns hiccup-find.core-test
-  (:require [midje.sweet :refer :all]
+  (:require [clojure.test :refer :all]
             [hiccup-find.core :refer :all]))

-(fact (hiccup-symbol-matches? :p :p.class) => true
-      (hiccup-symbol-matches? :p.class :p) => false
-      (hiccup-symbol-matches? :.class :p.class.more) => true
-      (hiccup-symbol-matches? :p.more.class :p.class.more) => true)
+(deftest test-hiccup-symbol-matches?
+  (is (hiccup-symbol-matches? :p :p.class))
+  (is (not (hiccup-symbol-matches? :p.class :p)))
+  (is (hiccup-symbol-matches? :.class :p.class.more))
+  (is (hiccup-symbol-matches? :p.more.class :p.class.more)))

-(fact (hiccup-find [:p.image]
-                   [:html
-                    [:body
-                     [:p.img "No"]
-                     [:p.image "Yes 1"]
-                     [:p.images "No"]
-                     [:div.image
-                      [:p.image "Yes 2"]]]])
-      => (list [:p.image "Yes 1"]
-               [:p.image "Yes 2"]))
+(deftest test-hiccup-find

-(fact (hiccup-find [:div :p]
-                   [:html
-                    [:body
-                     [:p "No"]
-                     [:div [:p "Yes 1"]]
-                     [:div
-                      [:table
-                       [:tr
-                        [:td
-                         [:p "Yes 2"]]]]]]])
-      => (list [:p "Yes 1"]
-               [:p "Yes 2"]))
+  (is (= (list [:p.image "Yes 1"]
+               [:p.image "Yes 2"])
+         (hiccup-find [:p.image]
+                      [:html
+                       [:body
+                        [:p.img "No"]
+                        [:p.image "Yes 1"]
+                        [:p.images "No"]
+                        [:div.image
+                         [:p.image "Yes 2"]]]])))

-(fact (hiccup-find [:div :p]
-                   [:html
-                    [:body
-                     [:div
-                      [:table
-                       [:tr
-                        [:td
-                         [:p "Yes 1"]]]]]
-                     [:div
-                      [:table
-                       [:tr
-                        [:td
-                         [:p "Yes 2"]]]
-                       [:tr
-                        [:td
-                         [:p "Yes 3"]]]]]]])
-      => (list [:p "Yes 1"]
+  (is (= (list [:p "Yes 1"]
+               [:p "Yes 2"])
+         (hiccup-find [:div :p]
+                      [:html
+                       [:body
+                        [:p "No"]
+                        [:div [:p "Yes 1"]]
+                        [:div
+                         [:table
+                          [:tr
+                           [:td
+                            [:p "Yes 2"]]]]]]])))
+
+  (is (= (list [:p "Yes 1"]
                [:p "Yes 2"]
-               [:p "Yes 3"]))
+               [:p "Yes 3"])
+         (hiccup-find [:div :p]
+                      [:html
+                       [:body
+                        [:div
+                         [:table
+                          [:tr
+                           [:td
+                            [:p "Yes 1"]]]]]
+                        [:div
+                         [:table
+                          [:tr
+                           [:td
+                            [:p "Yes 2"]]]
+                          [:tr
+                           [:td
+                            [:p "Yes 3"]]]]]]]))))

-(fact (hiccup-text [:p "Text here"])
-      => "Text here")
+(deftest test-hiccup-text
+  (is (= "Text here"
+         (hiccup-text [:p "Text here"])))

-(fact (hiccup-text [:p [:span "Text here"]])
-      => "Text here")
+  (is (= "Text here"
+         (hiccup-text [:p [:span "Text here"]])))

-(fact (hiccup-text [:p {:class "something"} "Text here"])
-      => "Text here")
+  (is (= "Text here"
+         (hiccup-text [:p {:class "something"} "Text here"])))

-(fact (hiccup-text [:p {:class "something"} "Text " [:strong "here"]])
-      => "Text here")
+  (is (= "Text here"
+         (hiccup-text [:p {:class "something"} "Text " [:strong "here"]])))

-(fact (hiccup-text [:html
-                    [:body
-                     [:h1 "Welcome, earthling"]
-                     [:p "Hope you " [:strong "enjoy"] " your stay"]]]) => (str "Welcome, earthling\n"
-                                                                                "Hope you enjoy your stay"))
+  (is (= (str "Welcome, earthling\n"
+              "Hope you enjoy your stay")
+         (hiccup-text [:html
+                       [:body
+                        [:h1 "Welcome, earthling"]
+                        [:p "Hope you " [:strong "enjoy"] " your stay"]]])))

-(fact (hiccup-text [:html
-                    [:body
-                     [:p "Number " [:strong 42]]]]) => "Number 42")
+  (is (= "Number 42"
+         (hiccup-text [:html
+                       [:body
+                        [:p "Number " [:strong 42]]]]))))
+(deftest test-hiccup-string
+  (is (= "Welcome, earthling Hope you enjoy your stay"
+         (hiccup-string [:html
+                         [:body
+                          [:h1 "Welcome, earthling"]
+                          [:p "Hope you " [:strong "enjoy"] " your stay"]]])))

-(fact (hiccup-string [:html
-                      [:body
-                       [:h1 "Welcome, earthling"]
-                       [:p "Hope you " [:strong "enjoy"] " your stay"]]]) => "Welcome, earthling Hope you enjoy your stay")
-
-(fact (hiccup-string [:html
-                      [:body
-                       [:h1 "Welcome!"]
-                       [:p "Hope you   " [:strong "enjoy"] " your stay"]]]) => "Welcome! Hope you enjoy your stay")
+  (is (= "Welcome! Hope you enjoy your stay"
+         (hiccup-string [:html
+                         [:body
+                          [:h1 "Welcome!"]
+                          [:p "Hope you   " [:strong "enjoy"] " your stay"]]]))))


Add test to prove that resolve- works.

Add test to prove that resolve- works.

--- test/isla/test/interpreter.clj
+++ test/isla/test/interpreter.clj
@@ -24,6 +24,15 @@
     (is (= (resolve- {:ref "friend"} env)
            (new isla.test.interpreter.Person 1 "" :undefined)))))

+(deftest test-lookup-resolves-object-slot-to-object-reference-with-updated-data
+  (let [env (interpret (parse "isla is a person
+                               mary is a person
+                               mary friend is isla
+                               isla age is 1")
+                       (library/get-initial-env extra-types))]
+    (is (= (resolve- {:ref "mary"} env)
+           (let [isla (new isla.test.interpreter.Person 1 "" :undefined)]
+             (new isla.test.interpreter.Person 0 "" isla))))))

 ;; invocation


Add evaluator bar

Add evaluator bar

--- src/obb_demo/views/play.cljs
+++ src/obb_demo/views/play.cljs
@@ -2,6 +2,8 @@
   (:require [obb-demo.state :as state]
             [obb-rules.game :as game]
             [obb-rules.stash :as stash]
+            [obb-rules.math :as math]
+            [obb-rules.evaluator :as evaluator]
             [obb-rules.turn :as turn]
             [obb-rules.result :as result]
             [obb-demo.boardground :as boardground]))
@@ -73,13 +75,25 @@
       " vs "
       [(selected-player player :p1) "Player 1"]]))

+(defn- power-bar
+  "Shows each player's power"
+  [game]
+  (let [[p1 p2] (evaluator/eval-game game)
+        total (+ p1 p2)
+        p1-perc (math/ceil (* 100 (/ (- total p1) total)))
+        p2-perc (- 100 p1-perc)]
+    [:div.progress {:style {:margin-top "10px"}}
+     [:div.progress-bar.progress-bar-info {:style {:width (str p1-perc "%")}} p1-perc]
+     [:div.progress-bar.progress-bar-success {:style {:width (str p2-perc "%")}} p2-perc]]))
+
 (defn render
   [state]
   (let [game-data (get-game-data state)
         game (:game game-data)]
     [:div.row
       [:div.col-lg-2
-       (players game)]
+       (players game)
+       (power-bar game)]
       [:div.col-lg-5
         [boardground/render {} game-data]]
       [:div.col-lg-2


assoc 'number :tag rather than :numeric true

--- src/main/clojure/clojure/tools/analyzer/js.clj
+++ src/main/clojure/clojure/tools/analyzer/js.clj
@@ -160,7 +160,7 @@
                                          op
                                          (symbol "cljs.core" (name op)))}
                                (when (-> clj-macro meta :cljs.core/numeric)
-                                 {:numeric true}))
+                                 {:tag 'number}))
                     ret)))
               (desugar-host-expr form env)))))
       (desugar-host-expr form env))))


Clean up task-metadata in gc

Clean up task-metadata in gc

--- src/onyx/log/commands/gc.clj
+++ src/onyx/log/commands/gc.clj
@@ -18,6 +18,7 @@
             (assoc x :completed-jobs [])
             (reduce (fn [new job] (update-in new [:tasks] dissoc job)) x jobs)
             (reduce (fn [new job] (update-in new [:allocations] dissoc job)) x jobs)
+            (reduce (fn [new job] (update-in new [:task-metadata] dissoc job)) x jobs)
             (reduce (fn [new job] (update-in new [:task-schedulers] dissoc job)) x jobs)
             (reduce (fn [new job] (update-in new [:percentages] dissoc job)) x jobs)
             (reduce (fn [new job] (update-in new [:task-percentages] dissoc job)) x jobs)


Eliminate remaining boxed-math warnings

Eliminate remaining boxed-math warnings

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -71,7 +71,7 @@

 (defn handle-aux-message [daemon release-ch retry-ch buffer offset length header]
   (let [msg-type (protocol/read-message-type buffer offset)
-        offset-rest (long (inc offset))]
+        offset-rest (inc ^long offset)]
     (cond (= msg-type protocol/ack-msg-id)
           (let [ack (protocol/read-acker-message buffer offset-rest)]
             (acker/ack-message daemon (:id ack) (:completion-id ack) (:ack-val ack)))
@@ -230,7 +230,7 @@
 (defmethod extensions/receive-messages AeronConnection
   [messenger {:keys [onyx.core/task-map] :as event}]
   (let [ch (:inbound-ch messenger)
-        batch-size (:onyx/batch-size task-map)
+        batch-size (long (:onyx/batch-size task-map))
         ms (arg-or-default :onyx/batch-timeout task-map)
         timeout-ch (timeout ms)]
     (loop [segments [] i 0]
@@ -253,7 +253,7 @@
         idle-strategy (:send-idle-strategy messenger)]
     ;;; TODO: offer will return a particular code when the publisher is down
     ;;; we should probably re-restablish the publication in this case
-    (while (neg? (offer-f))
+    (while (neg? ^long (offer-f))
       (.idle ^IdleStrategy idle-strategy 0))))

 (defmethod extensions/internal-ack-messages AeronConnection
@@ -264,7 +264,7 @@
     (doseq [{:keys [id completion-id ack-val]} acks]
       (let [unsafe-buffer (protocol/build-acker-message id completion-id ack-val)
             offer-f (fn [] (.offer pub unsafe-buffer 0 protocol/ack-msg-length))]
-        (while (neg? (offer-f))
+        (while (neg? ^long (offer-f))
           (.idle ^IdleStrategy idle-strategy 0))))))

 (defmethod extensions/internal-complete-message AeronConnection
@@ -273,7 +273,7 @@
         unsafe-buffer (protocol/build-completion-msg-buf id)
         pub ^uk.co.real_logic.aeron.Publication (get-peer-link-pub peer-link :aux-pub :aux-pub-f-create)
         offer-f (fn [] (.offer pub unsafe-buffer 0 protocol/completion-msg-length))]
-    (while (neg? (offer-f))
+    (while (neg? ^long (offer-f))
       (.idle ^IdleStrategy idle-strategy 0))))

 (defmethod extensions/internal-retry-message AeronConnection
@@ -282,7 +282,7 @@
         unsafe-buffer (protocol/build-retry-msg-buf id)
         pub ^uk.co.real_logic.aeron.Publication (get-peer-link-pub peer-link :aux-pub :aux-pub-f-create)
         offer-f (fn [] (.offer pub unsafe-buffer 0 protocol/retry-msg-length))]
-    (while (neg? (offer-f))
+    (while (neg? ^long (offer-f))
       (.idle ^IdleStrategy idle-strategy 0))))

 (defmethod extensions/close-peer-connection AeronConnection


Adding basic support for chord inversions.

* added an invert-chord function
* chord function now takes an optional inversion value

--- src/overtone/music/pitch.clj
+++ src/overtone/music/pitch.clj
@@ -11,10 +11,6 @@
 ;; Notes in a typical scale are related by small, prime number ratios. Of all
 ;; possible 7 note scales, the major scale has the highest number of consonant
 ;; intervals.
-
-(defn play
-  [s notes]
-  (doall (map #(s %) notes)))

 (defmacro defratio [rname ratio]
   `(defn ~rname [freq#] (* freq# ~ratio)))
@@ -436,6 +432,31 @@
     (CHORD chord)
     chord))

+(defn- inc-first
+  "Remove the first element, increment it by n, and append to seq."
+  [elems n]
+  (concat (next elems) [(+ n (first elems))]))
+
+(defn- dec-last
+  "Remove the last element, decrement it by n, and prepend to seq."
+  [elems n]
+  (concat [(- (last elems) n)] (next elems)))
+
+(defn invert-chord
+  "Move a chord voicing up or down.
+
+    ;first inversion
+    (invert-chord [60 64 67] 1) ;=> (64 67 72)
+
+    ; second inversion
+    (invert-chord [60 64 67] 1) ;=> (67 72 76)
+  "
+  [notes shift]
+  (cond
+    (pos? shift) (recur (inc-first notes 12) (dec shift))
+    (neg? shift) (recur (dec-last notes 12) (inc shift))
+    (zero? shift) notes))
+
 (defn chord
   "Returns a set of notes for the specified chord. The root must be in midi note
   format i.e. :C3.
@@ -445,9 +466,12 @@
   (chord :Bb4 :dim)   ; b flat diminished -> #{70 73 76}
   "
   ([root chord-name]
+   (chord root chord-name 0))
+  ([root chord-name inversion]
      (let [root (note root)
-           chord (resolve-chord chord-name)]
-       (set (map #(+ % root) chord)))))
+           chord (resolve-chord chord-name)
+           notes (map #(+ % root) chord)]
+       (invert-chord notes inversion))))

 (defn rand-chord
   "Generates a random list of MIDI notes with cardinality num-pitches bound


Cleaned up some of the ning integration

Cleaned up some of the ning integration

--- src/parbench/ning_client.clj
+++ src/parbench/ning_client.clj
@@ -17,20 +17,17 @@
               (enqueue (.success res-ch)
                        {:status status :content-type content-type})))
           (onThrowable [e]
-            (.printStackTrace e)
-            (log/error e "bad error for ning!")
+            (log/error e "We hit a throwable in Ning")
             (enqueue res-ch e))))

 (defn http-get
   "Convenience method to execute a GET request with the client"
   [url]
-  (let [requestConfig (doto (PerRequestConfig.)
-                      (.setRequestTimeoutInMs (int 2000)))
-        handler-res-ch (result-channel)
-        handler (client-handler handler-res-ch)]
-    (.execute
-      (.setPerRequestConfig
-        (.prepareGet client url)
-        requestConfig)
-      handler)
+  (let [handler-res-ch (result-channel)
+        handler (client-handler handler-res-ch)
+        requestConfig (doto (PerRequestConfig.)
+                            (.setRequestTimeoutInMs (int 2000)))]
+    (-> (.prepareGet client url)
+        (.setPerRequestConfig requestConfig)
+        (.execute handler))
     handler-res-ch))


:required attribute on input should be a boolean

--- frontend/components/account.cljs
+++ frontend/components/account.cljs
@@ -136,7 +136,7 @@
                           (.preventDefault event)
                           (create-token! (om/get-state owner :token-label)))}
             [:input#api-token
-             {:required  "",
+             {:required  true
               :name      "label",
               :type      "text",
               :value     (str (om/get-state owner :token-label))