logging improvements

logging improvements

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -153,7 +153,7 @@
                  (if (fail? result)
                    (do
                      (log/debug (str "comp precheck failed  for pair: " pair))
-                     (log/debug (str "comp precheck failed: parent wanted:" (strip-refs parent-value) ";"
+                     (log/debug (str "comp precheck failed: parent wanted: " (strip-refs parent-value) ";"
                                      "child has: " (strip-refs child-value)))
                      (log/trace (str " child is: " (strip-refs child)))
                      :fail)
@@ -254,8 +254,8 @@
 (defn moreover-comp [parent child lexfn-sem-impl]
   (log/trace (str "moreover-comp type parent: " (type parent)))
   (log/trace (str "moreover-comp type comp:" (type child)))
-  (log/debug (str "moreover-comp: child cat: " (get-in child [:synsem :cat])))
-  (log/debug (str "moreover-comp: parent comp cat: " (get-in parent [:comp :synsem :cat])))
+  (log/trace (str "moreover-comp: child cat: " (get-in child [:synsem :cat])))
+  (log/trace (str "moreover-comp: parent comp cat: " (get-in parent [:comp :synsem :cat])))

   (let [pre-check2 (comp-pre-checks2 parent child)
         pre-check (comp-pre-checks parent child)
@@ -299,7 +299,7 @@
              (map? head))
     (do
       (log/trace (str "overh: parent: " (get-in parent [:rule])))
-      (log/debug (str "overh: head: " (get-in head [:rule] (str "head is a lexeme with pred: " (strip-refs (get-in head [:synsem :sem :pred]))))))
+      (log/trace (str "overh: head: " (get-in head [:rule] (str "head is a lexeme with pred: " (strip-refs (get-in head [:synsem :sem :pred]))))))
       (log/trace (str "overh: parent: " (strip-refs (dissoc parent :serialized))))
       (log/trace (str "overh: head: " (strip-refs (dissoc head :serialized))))))


modal shroud

modal shroud

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -242,10 +242,9 @@
         no-stream? (not stream)]
     (dom/div #js {
       :className (str "modal" (when (or no-stream? media-error show-about? result-gif winner?) " active"))}
-      (dom/h1 nil "Cellf")
       (cond
         media-error
-          (dom/p nil
+          (dom/div nil
             (if (= media-error :denied)
               "Sorry, Cellf doesn't work without camera access."
               (str
@@ -254,7 +253,7 @@
             (dom/button #js {:onClick get-camera!} "try again"))

         no-stream?
-          (dom/p nil
+          (dom/div nil
             (str
               "Cellf is an interactive experiment that reflects the player and their "
               "surroundings as they play. Click OK to prompt for camera access.")
@@ -264,12 +263,12 @@
             (dom/button #js {:onClick get-camera!} "ok"))

         winner?
-          (dom/p nil
+          (dom/div nil
             "You win! For more of a challenge, drag the slider to create a bigger grid."
             (dom/button #js {:onClick #(set-grid-size! app grid-size)} "new game"))

         result-gif
-          (dom/p nil
+          (dom/div nil
             (dom/img #js {:src result-gif})
             "You can save this gif and share it with the world."
             (dom/button #js {:onClick #(om/update! app :result-gif nil)} "done"))


Cleanup output of ruby/methods

Cleanup output of ruby/methods

--- src/circle/ruby.clj
+++ src/circle/ruby.clj
@@ -240,4 +240,4 @@
 (defn methods
   "Returns the list of ruby methods on the obj"
   [obj]
-  (seq (send obj :methods)))+  (map #(symbol (str (.to_s %))) (seq (send obj :methods))))


position information added to xpaths-hrefs-tokens

--- src/crawler/dom.clj
+++ src/crawler/dom.clj
@@ -369,6 +369,34 @@
        ;;     concat acc {an-xpath [node]})) {} nodes-xpaths)
        nodes-paths)))

+(defn path->xpath
+  [path positions]
+  (clojure.string/join
+   "/"
+   (cons
+    "/"
+    (map
+     (fn [i]
+       (let [[tag class pos] (nth path i)]
+         (if (some #{i} (set positions))
+           (if class
+             (format "%s[contains(@class, '%s')][%d]" tag class (inc pos))
+             (format "%s[%d]" tag (inc pos)))
+           (if class
+             (format "%s[contains(@class, '%s')]" tag class)
+             (format "%s" tag)))))
+     (range
+      (count path))))))
+
+(defn generate-xpath
+  "Generates an xpath for a set of nodes by incoporating
+   position information"
+  [[positions nodes]]
+  (map
+   (fn [[path a-node]]
+     [(path->xpath path positions) a-node])
+   nodes))
+
 (defn xpaths-hrefs-tokens
   [nodes-paths]
   (let [node-objs     (map
@@ -422,5 +450,14 @@
                          #(map
                            :obj
                            (second %))
-                         grouped-nodes))]
-    pos-path-nodes))
+                         grouped-nodes))
+
+        xpath-nodes    (reduce
+                        concat
+                        (map generate-xpath
+                             pos-path-nodes))]
+    (reduce
+     (fn [acc v]
+       (merge-with concat acc {(first v) [(second v)]}))
+     {}
+     xpath-nodes)))


Draw labels for cue variables.

Draw labels for cue variables.

--- src/afterglow/controllers/ableton_push_2.clj
+++ src/afterglow/controllers/ableton_push_2.clj
@@ -528,6 +528,37 @@
     (.drawString graphics label (int (math/round (- (* (+ index 0.5) button-cell-width) (/ width 2))))
                  (- Wayang/DISPLAY_HEIGHT 4))))

+(defn- space-for-encoder-button-label
+  "Calculate how much room there is to draw a label under an encoder,
+  based on how many encoders the label applies to."
+  [encoder-count]
+  (- (* button-cell-width encoder-count) button-cell-margin))
+
+(def font-for-encoder-button-label
+  "The font used when drawing labels under encoders."
+  (get-display-font :condensed-light Font/PLAIN 14))
+
+(def encoder-label-underline-height
+  "The height at which to draw the line under an encoder label."
+  20.0)
+
+(defn draw-encoder-button-label
+  "Draw a label under an encoder at the top of the graphical display."
+  [controller index encoder-count text color]
+  (let [graphics (create-graphics controller)
+        space (space-for-encoder-button-label encoder-count)
+        metrics (.getFontMetrics graphics font-for-encoder-button-label)
+        label (fit-string text metrics space)
+        width (.stringWidth metrics label)]
+    (set-graphics-color graphics color)
+    (.setFont graphics font-for-encoder-button-label)
+    (.drawString graphics label
+                 (int (math/round (- (* (+ index (/ encoder-count 2)) button-cell-width) (/ width 2)))) 16)
+    (.draw graphics (java.awt.geom.Line2D$Double.
+                     (+ (* index button-cell-width) (/ button-cell-margin 2.0)) encoder-label-underline-height
+                     (- (* (+ index encoder-count) button-cell-width) (/ button-cell-margin 2.0) 1.0)
+                     encoder-label-underline-height))))
+
 (defn ^:deprecated make-gauge
   "Create a graphical gauge with an indicator that fills a line.
   The default range is from zero to a hundred, and the default size is
@@ -658,7 +689,8 @@
                          arrow-pos (if (in-mode? controller :shift)
                                      (dec (.indexOf marker "." (inc (.indexOf marker "."))))
                                      (dec (count marker)))]
-    #_(aset (get (:next-display controller) 2) arrow-pos 0)))
+    #_(aset (get (:next-display controller) 2) arrow-pos 0))
+  true)

 (defn- adjust-beat-from-encoder
   "Adjust the current beat based on how the encoder was twisted."
@@ -844,28 +876,32 @@
     1 (vec (repeat 2 (first cue-vars)))
     (vec (take 2 (drop var-offset (apply concat (repeat cue-vars)))))))

-(defn- fit-cue-variable-name
-  "Picks the best version of a cue variable name to fit in the specified
-  number of characters, then truncates it if necessary."
-  [v len]
-  (let [longer (or (:name v) (name (:key v)))
-        shorter (or (:short-name v) longer)
-        padding (clojure.string/join (repeat len " "))]
-    (if (<= (count longer) len)
-      (clojure.string/join (take len (str longer padding)))
-      (clojure.string/join (take len (str shorter padding))))))
-
-(defn- cue-variable-names
-  "Determines the names of adjustable variables to display under an
-  active cue."
-  [controller cue effect-id]
+(defn- best-cue-variable-name
+  "Picks the best version of a cue variable name to fit under the
+  specified number of encoders."
+  [controller v encoder-count]
+  (let [graphics (create-graphics controller)
+        space (space-for-encoder-button-label encoder-count)
+        font font-for-encoder-button-label
+        metrics (.getFontMetrics graphics font)
+        longer (or (:name v) (name (:key v)))
+        shorter (or (:short-name v) longer)]
+    (if (<= (.stringWidth metrics longer) space) longer shorter)))
+
+(defn draw-cue-variable-names
+  "Draw the names of adjustable variables under the appropriate
+  encoders for a cue."
+  [controller x cue effect-id]
   (let [cue-vars (cue-vars-for-encoders (:variables cue) (get @(:cue-var-offsets controller) effect-id 0))]
-    (if (seq cue-vars)
+    (when (seq cue-vars)
       (if (= (count (:variables cue)) 1)
-        (fit-cue-variable-name (first cue-vars) 17)
-        (str (fit-cue-variable-name (first cue-vars) 8) " "
-             (fit-cue-variable-name (second cue-vars) 8)))
-      "")))
+        (draw-encoder-button-label controller (* x 2) 2
+                                   (best-cue-variable-name controller (first cue-vars) 1) white-color)
+        (do
+          (draw-encoder-button-label controller (* x 2) 1
+                                     (best-cue-variable-name controller (first cue-vars) 1) white-color)
+          (draw-encoder-button-label controller (inc (* x 2)) 1
+                                     (best-cue-variable-name controller (second cue-vars) 1) white-color))))))

 (defn- fit-cue-variable-value
   "Truncates the current value of a cue variable to fit available
@@ -969,7 +1005,7 @@
                                   (if (= cur-vals saved-vals) :clear :save)
                                   (when (not= cur-vals (:starting-vars info))
                                     :save)))]
-              (write-display-cell controller 0 x (cue-variable-names controller cue (:id info)))
+              (draw-cue-variable-names controller x cue (:id info))
               (write-display-cell controller 1 x (cue-variable-values controller cue (:id info)))
               (set-graphics-color graphics color)
               (.fillRect graphics (+ left (/ button-cell-margin 2.0)) (- Wayang/DISPLAY_HEIGHT 38)
@@ -981,12 +1017,7 @@
                 (set-graphics-color graphics off-color)
                 (.setFont graphics label-font)
                 (.drawString graphics label (int (math/round (- (+ left button-cell-width) (/ label-width 2))))
-                             (- Wayang/DISPLAY_HEIGHT 23))
-                )
-              #_(.draw graphics (java.awt.geom.Line2D$Double.
-                               (+ left (/ button-cell-margin 2.0)) effect-underline-height
-                               (+ left (- width (/ button-cell-margin 2.0))) effect-underline-height))
-              (write-display-cell controller 2 x (or (:name cue) (:name (first fx))))
+                             (- Wayang/DISPLAY_HEIGHT 23)))
               (if (in-mode? controller :record)
                 (when save-action
                   (let [save-color (case save-action


log supervisor startup with id

log supervisor startup with id

--- src/clj/backtype/storm/daemon/supervisor.clj
+++ src/clj/backtype/storm/daemon/supervisor.clj
@@ -311,6 +311,7 @@
                            (when @active (conf SUPERVISOR-MONITOR-FREQUENCY-SECS))
                            )
                          :priority Thread/MAX_PRIORITY)]))]
+    (log-message "Starting supervisor with id " supervisor-id)
     (reify
      Shutdownable
      (shutdown [this]


Add enumeration-values fn to xml.spec

Add enumeration-values fn to xml.spec

Chris wrote this to look up valid values for enumerated-value elements according to the XML schema. We will use it to run validations on these elements.

--- src/vip/data_processor/validation/xml/spec.clj
+++ src/vip/data_processor/validation/xml/spec.clj
@@ -119,3 +119,9 @@
   {:pre [(contains? spec-docs version)]}
   (->> (paths-for-type type version)
        (map (partial str/join "."))))
+
+(defn enumeration-values [type version]
+  (let [query (str "//xs:simpleType[@name='" type "']//xs:enumeration")]
+    (->> (query->elements query version)
+         (map #(.getAttribute % "value"))
+         set)))


Support propagation of plain session data in SerializingSessionStore

--- systems/ring-session-cassandra/src/containium/utils/session_store.clj
+++ systems/ring-session-cassandra/src/containium/utils/session_store.clj
@@ -7,13 +7,44 @@
             [taoensso.nippy :as nippy]))

-(defrecord SerializingSessionStore [session-store serialize deserialize]
+;;; Helper methods.
+
+(defn deep-merge
+  "Like merge-with, but merges maps recursively."
+  [& maps]
+  (apply
+   (fn m [& maps]
+     (if (every? map? maps)
+       (apply merge-with m maps)
+       (last maps)))
+   maps))
+
+
+(defn deep-unmerge
+  [m kss]
+  (reduce (fn [[extracted leftover] ks]
+            [(assoc-in extracted ks (get-in m ks))
+             (update-in leftover (butlast ks) dissoc (last ks))])
+          [{} m]
+          kss))
+
+
+;;; Serializing session store.
+
+(def default-plain
+  [[:noir :session/longlived]
+   [:containium/last-db-write]])
+
+
+(defrecord SerializingSessionStore [session-store serialize deserialize options]
   SessionStore
   (read-session [_ key]
-    (when-let [data (::serialized (session/read-session session-store key))]
-      (deserialize data)))
+    (when-let [data (session/read-session session-store key)]
+      (deep-merge data (deserialize (::serialized data)))))
   (write-session [_ key data]
-    (session/write-session session-store key {::serialized (serialize data)}))
+    (let [[plain to-serialize] (deep-unmerge data (:plain options))
+          serialized (assoc plain ::serialized (serialize to-serialize))]
+      (session/write-session session-store key serialized)))
   (delete-session [this key]
     (session/delete-session session-store key)))

@@ -22,6 +53,7 @@
   ([session-store]
      (mk-session-store session-store nil))
   ([session-store {:keys [serializer deserializer]
-                                 :or {serializer nippy/freeze deserializer nippy/thaw}
-                                 :as options}]
-     (SerializingSessionStore. session-store (or serializer identity) (or deserializer identity))))
+                   :or {serializer nippy/freeze, deserializer nippy/thaw}
+                   :as options}]
+     (SerializingSessionStore. session-store (or serializer identity) (or deserializer identity)
+                               (merge {:plain default-plain} options))))


(PDB-4807) services-test: change start-ex to an atom

Doesn't need to be a promise.

--- test/puppetlabs/puppetdb/cli/services_test.clj
+++ test/puppetlabs/puppetdb/cli/services_test.clj
@@ -200,17 +200,17 @@
   ;; Intercept and validate both the throw from start-puppetdb and the
   ;; subsequent shutdown request from start.
   (let [service (atom nil)
-        start-ex (promise)
+        start-ex (atom nil)
         orig-start svcs/start-puppetdb
         start (fn [& args]
                 (let [[context config svc get-endpts request-shutdown upgrade?] args]
                   (reset! service svc)
                   (try
                     (let [result (apply orig-start args)]
-                      (deliver start-ex nil)
+                      (reset! start-ex nil)
                       result)
                     (catch Exception ex
-                      (deliver start-ex ex)
+                      (reset! start-ex ex)
                       (throw ex)))))
         err-msg? #(re-matches #"PostgreSQL 9\.5 is no longer supported\. .*" %1)]

@@ -222,7 +222,7 @@
         true))

     (testing "unsupported db triggers unsupported-database exception"
-      (let [ex (deref start-ex 0 nil)
+      (let [ex (deref start-ex)
             expected-oldest scf-store/oldest-supported-db
             {:keys [kind current oldest]} (when (instance? ExceptionInfo ex)
                                             (ex-data ex))]
@@ -242,7 +242,7 @@
   (let [bad-setting :standard_conforming_strings
         bad-value "off"
         service (atom nil)
-        start-ex (promise)
+        start-ex (atom nil)
         orig-req svcs/request-database-settings
         request-settings #(for [{n :name :as settings} (orig-req)]
                             (if (= n (name bad-setting))
@@ -254,10 +254,10 @@
                   (reset! service svc)
                   (try
                     (let [result (apply orig-start args)]
-                      (deliver start-ex nil)
+                      (reset! start-ex nil)
                       result)
                     (catch Exception ex
-                      (deliver start-ex ex)
+                      (reset! start-ex ex)
                       (throw ex)))))
         err-msg? #(re-matches #"Invalid database configuration settings: 'standard_.*" %1)]

@@ -269,7 +269,7 @@
         true))

     (testing "invalid-database-configuration exception thrown"
-      (let [ex (deref start-ex 0 nil)
+      (let [ex (deref start-ex)
             {:keys [kind failed-validation]} (when (instance? ExceptionInfo ex)
                                                (ex-data ex))]
         (is (= ExceptionInfo (class ex)))


Put public function at the top for readability.

--- src/clj/made_merits/service/winner_calculator.clj
+++ src/clj/made_merits/service/winner_calculator.clj
@@ -1,6 +1,13 @@
 (ns made-merits.service.winner-calculator
   (:require [clojure.set :as set]
             [clojure.walk :as walk]))
+
+(defn with-winner
+  [scored-users]
+  (let [users-with-status (with-status scored-users)]
+    (if (more-than-one-winner? users-with-status)
+      (mark-everyone-as-a-loser users-with-status)
+      users-with-status)))

 (defn- with-status
   [scored-users]
@@ -27,10 +34,3 @@
           (walk/keywordize-keys
             (frequencies
               (map :status users-with-status))))))
-
-(defn with-winner
-  [scored-users]
-  (let [users-with-status (with-status scored-users)]
-    (if (more-than-one-winner? users-with-status)
-      (mark-everyone-as-a-loser users-with-status)
-      users-with-status)))


Fix up main fn to serve or run once based on args.

--- src/incise/core.clj
+++ src/incise/core.clj
@@ -28,46 +28,51 @@
         (cli args
              (:doc (meta (the-ns 'incise.core)))
              ["-h" "--help" "Print this help." :default false :flag true]
+             ["-1" "--once" "Instead of running in server mode run once."
+              :default false :flag true]
              ["-i" "--in-dir" "The directory to get source from"]
              ["-o" "--out-dir" "The directory to put content into"])]
     (conf/merge options)
     (if (:help options)
-      (println banner)
-      (body-fn cli-args))
-    (when *file* (System/exit 0))))
+      (do (println banner)
+          (System/exit 0))
+      (body-fn cli-args))))

 (defmacro with-args
   "Take arguments parsing them using cli and handle help accordingly."
   [args & body]
   `(with-args* ~args (fn [~'args] ~@body)))

+(defn once
+  "Incise just once."
+  [& [load-config]]
+  (when-not (false? load-config) (conf/load))
+  (let [out-dir (conf/get :out-dir)
+        stefon-pre-opts {:cache-mode :production
+                         :compress true
+                         :serving-root out-dir
+                         :precompiles (conf/get :precompiles)}]
+    (info "Clearing out" (str \" out-dir \"))
+    (delete-recursively (file out-dir))
+    (with-options stefon-pre-opts
+      (info "Precompiling assets...")
+      (info (with-out-str (dc/precompile)))
+      (info "Done.")
+      (load-parsers-and-layouts)
+      (->> (conf/get :in-dir)
+           (file)
+           (file-seq)
+           (map (wrap-log-exceptions parse))
+           (dorun)))))
+
 (defn -main
   "Start the development server and watcher."
   [& args]
   (with-args args
-    (serve)))
-
-(defn once
-  "Incise "
-  [& args]
-  (with-args args
-    (let [out-dir (conf/get :out-dir)
-          stefon-pre-opts {:cache-mode :production
-                           :compress true
-                           :serving-root out-dir
-                           :precompiles (conf/get :precompiles)}]
-      (info "Clearing out" (str \" out-dir \"))
-      (delete-recursively (file out-dir))
-      (with-options stefon-pre-opts
-        (info "Precompiling assets...")
-        (info (with-out-str (dc/precompile)))
-        (info "Done.")
-        (load-parsers-and-layouts)
-        (->> (conf/get :in-dir)
-             (file)
-             (file-seq)
-             (map (wrap-log-exceptions parse))
-             (dorun))))))
+    (if (conf/get :once)
+      (do (once false)
+          (System/exit 0))
+      (serve))))

 (defn restart
   "Define a server and set up a watcher AT THE SAME TIME!"


CMR-981: Addressed review comments.

CMR-981: Addressed review comments.

--- umm-lib/src/cmr/umm/validation/product_specific_attribute.clj
+++ umm-lib/src/cmr/umm/validation/product_specific_attribute.clj
@@ -6,12 +6,12 @@
             [cmr.umm.collection.product-specific-attribute :as psa]))

 (def no-range-data-types
-  "List of data-types of additional attribute that do not support parameter range"
-  [:string :boolean])
+  "Set of data-types of additional attribute that do not support parameter range"
+  #{:string :boolean})

 (def validate-range-data-types
-  "List of data-types of additional attribute that require parameter range validations"
-  [:int :float :datetime :date :time])
+  "Set of data-types of additional attribute that require parameter range validations"
+  #{:int :float :datetime :date :time})

 (defn- data-type-validator
   "Validates data-type is one of the valid product specific attribute data types"
@@ -50,48 +50,31 @@
                    (when value
                      [(format "%s is not allowed for type [%s]"
                               (v/humanize-field field) (psa/gen-data-type data-type))]))]
-    (when (some #{data-type} no-range-data-types)
+    (when (no-range-data-types data-type)
       (->> (select-keys aa [:parameter-range-begin :parameter-range-end])
            (mapcat #(apply value-fn %))
            (remove nil?)))))
-
-(defprotocol CompareValues
-  "Protocol to compare two values"
-  (greater-than
-    [obj1 obj2]
-    "Returns true if obj1 is greater than obj2"))
-
-(extend-protocol CompareValues
-  org.joda.time.DateTime
-  (greater-than
-    [obj1 obj2]
-    (t/after? obj1 obj2))
-
-  java.lang.Object
-  (greater-than
-    [obj1 obj2]
-    (> obj1 obj2)))

 (defn- range-values-validation
   "Validates range values"
   [aa]
   (let [{:keys [data-type parsed-parameter-range-begin parsed-parameter-range-end parsed-value]} aa]
-    (when (some #{data-type} validate-range-data-types)
+    (when (validate-range-data-types data-type)
       (cond
         (and parsed-parameter-range-begin parsed-parameter-range-end
-             (greater-than parsed-parameter-range-begin parsed-parameter-range-end))
+             (> (compare parsed-parameter-range-begin parsed-parameter-range-end) 0))
         [(format "Parameter Range Begin [%s] cannot be greater than Parameter Range End [%s]."
                  (psa/gen-value data-type parsed-parameter-range-begin)
                  (psa/gen-value data-type parsed-parameter-range-end))]

         (and parsed-value parsed-parameter-range-begin
-             (greater-than parsed-parameter-range-begin parsed-value))
+             (< (compare parsed-value parsed-parameter-range-begin) 0))
         [(format "Value [%s] cannot be less than Parameter Range Begin [%s]."
                  (psa/gen-value data-type parsed-value)
                  (psa/gen-value data-type parsed-parameter-range-begin))]

         (and parsed-value parsed-parameter-range-end
-             (greater-than parsed-value parsed-parameter-range-end))
+             (> (compare parsed-value parsed-parameter-range-end) 0))
         [(format "Value [%s] cannot be greater than Parameter Range End [%s]."
                  (psa/gen-value data-type parsed-value)
                  (psa/gen-value data-type parsed-parameter-range-end))]))))


correction of a bug introduced with the activate paredit preference

--- ccw.core/src/ccw/editors/antlrbased/PareditAutoEditStrategy.clj
+++ ccw.core/src/ccw/editors/antlrbased/PareditAutoEditStrategy.clj
@@ -30,8 +30,8 @@

 (defn -customizeDocumentCommand
   [#^IAutoEditStrategy this, #^IDocument document, #^DocumentCommand command]
-  (when (paredit-enabled? (-> this .state deref :prefs-store))
-        (and (.doit command)
+  (when (and (paredit-enabled? (-> this .state deref :prefs-store))
+             (.doit command)
              (= 0 (.length command))
              (contains? *one-char-command* (.text command)))
     (let [result (paredit (get *one-char-command* (.text command))


TNS-3: Actually use 'refresh-dirs' in 'refresh'

JIRA: http://dev.clojure.org/jira/browse/TNS-3

--- src/main/clojure/clojure/tools/namespace/repl.clj
+++ src/main/clojure/clojure/tools/namespace/repl.clj
@@ -42,7 +42,8 @@

 (defn- do-refresh [scan-fn]
   (let [current-ns (ns-name *ns*)]
-    (alter-var-root #'refresh-tracker scan-fn)
+    (alter-var-root #'refresh-tracker
+                    #(apply scan-fn % refresh-dirs))
     (alter-var-root #'refresh-tracker remove-disabled)
     (print-pending-reloads refresh-tracker)
     (alter-var-root #'refresh-tracker reload/track-reload)


Graaagh

Graaagh

--- src/korhal/core.clj
+++ src/korhal/core.clj
@@ -67,7 +67,7 @@
         (let [mineral? (fn [unit] (= (.getTypeID unit) (.getID jnibwapi.types.UnitType$UnitTypes/Resource_Mineral_Field)))
               minerals (first (filter mineral? (.getNeutralUnits (:api @(.state this)))))
               closest-mineral (first (filter #(< (dist unit %) 300) minerals))]
-          (.rightClick (:api @(.state this)) (.getID unit) (.getID closest-mineral))))))))
+          (.rightClick (:api @(.state this)) (.getID unit) (.getID closest-mineral)))))))


use keyword for status in filter groups (#732)

--- src/cljs/main/broadfcui/page/workspace/monitor/submission_details.cljs
+++ src/cljs/main/broadfcui/page/workspace/monitor/submission_details.cljs
@@ -83,7 +83,7 @@
                                                      workflow-name "/" workflowId "/")})))}]
        :filter-groups
        (vec (cons {:text "All" :pred (constantly true)}
-                  (map (fn [status] {:text status :pred #(= status (% "status"))})
+                  (map (fn [status] {:text status :pred #(= status (:status %))})
                        moncommon/wf-all-statuses)))
        :data (:workflows props)
        :->row (fn [row]


Fix goog import

Fix goog import

--- src/javascript_externs_generator/extern.cljs
+++ src/javascript_externs_generator/extern.cljs
@@ -1,7 +1,6 @@
 (ns javascript-externs-generator.extern
   (:require [goog.dom :as dom]
             [goog.object :as obj]
-            [goog :as g]
             [clojure.string :as string]))

 (defn get-type
@@ -14,7 +13,7 @@
 (defn parent-type?
   "Whether it is possible for this object to have child properties"
   [obj]
-  (or (= (g/typeOf obj) "object")
+  (or (= (goog/typeOf obj) "object")
       (fn? obj)))

 (defn build-tree


test fix

test fix

--- src/metabase/driver/generic_sql/metadata.clj
+++ src/metabase/driver/generic_sql/metadata.clj
@@ -6,9 +6,9 @@
   [{:keys [db table name]}]
   (-> ((:native-query @db)
        (format "SELECT COUNT(\"%s\".\"%s\") AS count FROM \"%s\""
-               (:name (table))
+               (:name @table)
                name
-               (:name (table))))
+               (:name @table)))
       first
       :count))

@@ -16,8 +16,8 @@
   [{:keys [db table name]}]
   (-> ((:native-query @db)
        (format "SELECT COUNT(DISTINCT \"%s\".\"%s\") AS count FROM \"%s\""
-               (:name (table))
+               (:name @table)
                name
-               (:name (table))))
+               (:name @table)))
       first
       :count))


Fix HSL to RGB conversion.

Fix HSL to RGB conversion.

Turns out cubehelix uses a special conversion which is not generally
applicable.

--- src/org/playasophy/wonderdome/util/color.clj
+++ src/org/playasophy/wonderdome/util/color.clj
@@ -175,13 +175,12 @@
   a cone. This means a lightness of 0.0 is black, as with HSV, but 1.0 gives
   white instead of a 'fully bright' color."
   [h s l]
-  (let [hr (* h 2 Math/PI)
-        cos-h (Math/cos hr)
-        sin-h (Math/sin hr)]
-    (rgb
-      (+ l (* s (+ (* -0.14861 cos-h) (* 1.78277 sin-h))))
-      (+ l (* s (- (* -0.29227 cos-h) (* 0.90649 sin-h))))
-      (+ l (* s    (*  1.97294 cos-h))))))
+  (let [l' (* 2 l)
+        s' (* s (if (> l' 1) (- 2 l') l'))
+        s-div (+ l' s')
+        s' (if (zero? s-div) 0.0 (/ (* 2 s') s-div))
+        v' (/ (+ l' s') 2)]
+    (hsv h s' v')))

 (defmethod pack :hsl
@@ -210,7 +209,7 @@

-;;;;; COLOR GRADIENTS ;;;;;
+;;;;; COLOR BLENDING ;;;;;

 (defn blend-rgb
   "Blends two colors by linearly interpolating their red, green, and blue
@@ -264,9 +263,18 @@
          [dh ds dl] (map - yc xc)
          h (+ xh 1/3 (* p dh))
          l (Math/pow (+ xl (* p dl)) gamma)
-         s (* (+ xs (* p ds)) l (- 1 l))]
-     (hsl h s l))))
-
+         s (* (+ xs (* p ds)) l (- 1 l))
+         hr (* h 2 Math/PI)
+         cos-h (Math/cos hr)
+         sin-h (Math/sin hr)]
+     (rgb
+       (+ l (* s (+ (* -0.14861 cos-h) (* 1.78277 sin-h))))
+       (+ l (* s (- (* -0.29227 cos-h) (* 0.90649 sin-h))))
+       (+ l (* s    (*  1.97294 cos-h)))))))
+
+
+
+;;;;; COLOR GRADIENTS ;;;;;

 (defn gradient   ; FIXME: model after D3's linear scale
   "Assigns a color based on the position through a gradient of color points.


(SERVER-115) Avoid potential corruption by serializing crl writes

Note that this is just a trivial mitigation -- it does not prevent
corruption that might result from a server crash while writing, nor
does it prevent simultaneous crl read operations from seeing partial
updates.

To fix those, we might rework the code to make the updates to a temp
file while holding the lock, and then use Files/move to ATOMIC_MOVE
the update into place.

--- src/clj/puppetlabs/services/ca/certificate_authority_core.clj
+++ src/clj/puppetlabs/services/ca/certificate_authority_core.clj
@@ -34,6 +34,10 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; 'handler' functions for HTTP endpoints

+;; Perhaps this could/should be in the tk context somewhere, and of
+;; course it'll need to be used to guard any competing writes.
+(def crl-write-serializer (Object.))
+
 (defn handle-get-certificate
   [subject {:keys [cacert signeddir]}]
   (-> (if-let [certificate (ca/get-certificate subject cacert signeddir)]
@@ -286,7 +290,8 @@
   :put!
   (fn [context]
     (let [desired-state (get-desired-state context)]
-      (ca/set-certificate-status! settings subject desired-state)
+      (locking crl-write-serializer
+        (ca/set-certificate-status! settings subject desired-state))
       (-> context
         (assoc-in [:representation :media-type] "text/plain")))))


comments

comments

--- src/babel/francais/morphology/verbs.cljc
+++ src/babel/francais/morphology/verbs.cljc
@@ -1044,7 +1044,7 @@

 (def irregular-conjugations
   (concat
-   [;; conditional
+   [;; irregular conditional with :future-stem
     {:prefix :future-stem :suffix "ais"
      :unify-with {:synsem {:cat :verb
                            :agr {:person :1st
@@ -1081,7 +1081,7 @@
                                  :number :plur}
                            :infl :conditional}
                   :français {:conditional {:stem true}}}}
-    ;; future
+    ;; irregular future with :future-stem
     {:prefix :future-stem :suffix "ai"
      :unify-with {:synsem {:cat :verb
                            :agr {:person :1st
@@ -1119,7 +1119,7 @@
                            :infl :future}
                   :français {:future {:stem true}}}}

-    ;; imperfect
+    ;; imperfect with :imperfect-stem
     {:prefix :imperfect-stem :suffix "ais"
      :unify-with {:synsem {:cat :verb
                            :agr {:person :1st
@@ -1157,6 +1157,9 @@
                            :infl :imperfect}
                   :français {:imperfect {:stem true}}}}

+    ;; present with :boot-stem1 and :boot-stem2.
+    ;; :boot-stem1 is the "boot" itself (1sing,2sing,3sing,3plur)
+    ;; whereas :boot-stem2 is the remainder besides the "boot" (1plur,2plur)
     {:prefix :boot-stem1 :suffix "s"
      :unify-with {:synsem {:cat :verb
                            :agr {:person :1st


cleanup

cleanup

--- src/babel/italiano/morphology/verbs.cljc
+++ src/babel/italiano/morphology/verbs.cljc
@@ -84,85 +84,6 @@
      regular-past-source)))

 ;; </passato>
-
-(defonce patterns-present-tense
-  (compile-patterns
-   {:synsem {:infl :present}}
-   [{:agr {:synsem {:subcat {:1 {:agr {:number :sing
-                                       :person :1st}}}}}
-     :p [
-         #"(.*)o$"         "$1are"
-         #"(.*)o$"         "$1ere"
-         #"(.*)isco$"      "$1ire"
-         #"(.*)o$"         "$1ire"
-         #"(.*)o$"         "$1arsi" ;; alzo -> alzarsi
-         #"(.*)o$"         "$1irsi" ;; diverto -> divertirso
-         #"(.*)ico$"       "$1ire" ;; dico -> dire
-         ]}
-    {:agr {:synsem {:subcat {:1 {:agr {:number :sing
-                                       :person :2nd}}}}}
-     :p [
-         #"(.*)i$"         "$1are" ;; lavi -> lavare
-         #"(.*)i$"         "$1iare" ;; studi -> studiare
-         #"(.*)i$"         "$1arsi" ;; lavi -> lavarsi
-         #"(.*)cci$"       "$1cciare" ;; abbracci -> abbracciare
-         #"(.*)i$"         "$1ere"
-         #"(.*)i$"         "$1ire" ;; senti -> sentire
-         #"(.*c)hi$"       "$1are" ;; cerchi -> cercare
-         #"(.*)i$"         "$1iarsi" ;; arrabi -> arrabiarsi
-         #"(.*)sci$"       "$1re" ;; finisci -> finire
-         #"(.*)i$"         "$1irsi" ;; diverti -> divertirsi
-         #"(.*)ici$"       "$1ire" ;; dici -> dire
-         #"(.*)hi$"        "$1are" ;; pieghi -> piegare
-         ]}
-
-    {:agr {:synsem {:subcat {:1 {:agr {:number :sing
-                                       :person :3rd}}}}}
-
-     :p [
-         #"(.*)a$"         "$1are"
-         #"(.*)e$"         "$1ere"
-         #"(.*)e$"         "$1ire"
-         #"(.*)a$"         "$1arsi" ;; prepara -> preperarsi
-         #"(.*)sce$"       "$1re" ;; finisce -> finire
-         #"(.*)te$"        "$1tirsi" ;; diverte -> divertirsi
-         #"(.*)ice$"       "$1ire" ;; dice -> dire
-         ]}
-
-    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
-                                       :person :1st}}}}}
-     :p [
-         #"(.*)iamo$"      "$1are"  ;; parliamo -> parlare
-         #"(.*)iamo$"      "$1iare" ;; mangiamo -> mangiare
-         #"(.*)iamo$"      "$1ere"
-         #"(.*)iamo$"      "$1ire"
-         #"(.*c)hiamo$"    "$1are" ;; sprechiamo -> sprecare
-         #"(.*)iamo$"      "$1iarsi" ;; arrabiamo -> arrabiarsi
-         #"(.*)iamo$"      "$1arsi" ;; chiamiamo -> chiamarsi
-         #"(.*)iamo$"      "$1irsi" ;; divertiamo -> divertirsi
-         #"(.*)ciamo$"     "$1re" ;; diciamo -> dire
-         #"(.*)hiamo$"     "$1are" ;; pieghiamo -> piegare
-         ]}
-
-    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
-                                       :person :2nd}}}}}
-     :p [
-         #"(.*)([aei])te$" "$1$2re" ;; parlate -> parlare
-         #"(.*)([aei])te$" "$1$2rsi" ;; chiamate -> chiamarsi
-         ]}
-
-    {:agr {:synsem {:subcat {:1 {:agr {:number :plur
-                                       :person :3rd}}}}}
-     :p [
-         #"(.*)ano$"       "$1are"
-         #"(.*)ono$"       "$1ere"
-         #"(.*)ono$"       "$1ire"
-         #"(.*)ano$"       "$1arsi" ;; alzano -> alzarsi
-         #"(.*)scono$"     "$1re" ;; finiscono -> finire
-         #"(.*)ono$"       "$1irsi" ;; divertono -> divertirsi
-         #"(.*)cono$"      "$1re" ;; dicono -> dire
-         #"(.*)ono$"       "$1irsi" ;; vestono -> vestirsi
-         ]}]))

 (defonce patterns-conditional-tense
   (compile-patterns
@@ -420,7 +341,7 @@
         patterns-imperfect
         patterns-past-tense
         patterns-present-subjunctive
-        patterns-present-tense)))
+        patterns-present)))

 (defonce exceptions-rules
   [;; 1. past-tense exceptions


Move doall to the end of get-specs

Move doall to the end of get-specs

--- src/hu/ssh/github_changelog/dependencies/bundler.clj
+++ src/hu/ssh/github_changelog/dependencies/bundler.clj
@@ -4,10 +4,11 @@
     [clojure.java.io :as io]))

 (defn- get-specs [reader]
-  (->> (doall (line-seq reader))
+  (->> (line-seq reader)
        (drop-while #(not= % "  specs:"))
        (drop 1)
-       (take-while seq)))
+       (take-while seq)
+       doall))

 (defn- parse-spec [spec]
   {:name (second spec) :version (nth spec 2)})


Removed dsets_combining.clj

Removed dsets_combining.clj

--- clojure/org/gavrog/clojure/dsets_combining.clj
+++ clojure/org/gavrog/clojure/dsets_combining.clj
@@ -1,60 +0,0 @@
-(ns org.gavrog.clojure.dsets-combining
-  (:use (org.gavrog.clojure
-          [generators :only [make-backtracker results]]
-          [simple-generators :only [integer-partitions]]
-          [delaney]
-          [combineTiles])))
-
-(defn- circuit [n]
-  (assert (even? n))
-  (let [elms (range 1 (inc n))
-        circ (fn [i] (inc (mod (dec i) n)))
-        cinc (fn [i] (circ (inc i)))
-        cdec (fn [i] (circ (dec i)))]
-    (make-dsymbol 1
-                  n
-                  {0 (into {} (for [i elms]
-                                [i (if (odd? i) (cinc i) (cdec i))]))
-                   1 (into {} (for [i elms]
-                                [i (if (odd? i) (cdec i) (cinc i))]))}
-                  {})))
-
-(defn- chain [n i]
-  (assert (#{0 1} i))
-  (let [elms (range 1 (inc n))
-        op-a (fn [i] (cond ((if (odd? n) #{1} #{1 n}) i) i
-                           (even? i) (inc i)
-                           :else (dec i)))
-        op-b (fn [i] (cond (and (odd? n) (= n i)) i
-                           (even? i) (dec i)
-                           :else (inc i)))
-        [op-0 op-1] (if (zero? i) [op-a op-b] [op-b op-a])]
-    (make-dsymbol 1 n {0 (into {} (for [i elms] [i (op-0 i)]))
-                       1 (into {} (for [i elms] [i (op-1 i)]))} {})))
-
-(defn- orbit-lists [sizes]
-  (let [sizes (vec sizes)
-        n (count sizes)
-        make-orbit (fn [n i] (if (= i 2) (circuit n) (chain n i)))]
-    (make-backtracker
-      {:root []
-       :extract (fn [xs]
-                  (when (= n (count xs))
-                    (reduce append (dsymbol "0 1") (map make-orbit sizes xs))))
-       :children (fn [xs]
-                   (let [m (count xs)]
-                     (when (< m n)
-                       (if (odd? (nth sizes m))
-                         [(conj xs 0)]
-                         (let [k (if (and (> m 0)
-                                          (= (nth sizes m) (nth sizes (dec m))))
-                                   (nth xs (dec m))
-                                   0)]
-                           (for [i (range k 3)] (conj xs i)))))))})))
-
-(defn dsets2d [max-size]
-  (for [s (range 1 (inc max-size))
-        sizes (results (integer-partitions s))
-        olist (results (orbit-lists (reverse sizes)))
-        ds (results (combine-tiles olist))]
-    ds))


Enable snippet for cljs for `quadratic-vertex` as it is supported by p5js. Issue #255.

--- src/cljc/quil/snippets/shape/vertex.cljc
+++ src/cljc/quil/snippets/shape/vertex.cljc
@@ -110,27 +110,26 @@
   (q/curve-vertex 0 0 0)
   (q/end-shape :close))

-#?(:clj
-   (defsnippet quadratic-vertex
-     "quadratic-vertex"
-     {:renderer :p3d}
-
-     (q/camera 50 200 50 50 0 0 0 0 -1)
-     (q/line 0 0 0 0 0 100)
-     (q/line 0 0 0 0 100 0)
-     (q/line 0 0 0 100 0 0)
-     (q/begin-shape)
-     (q/vertex 0 0)
-     (q/quadratic-vertex 30 50 10 100)
-     (q/quadratic-vertex 50 -50 90 100)
-     (q/quadratic-vertex 80 50 100 0)
-     (q/end-shape :close)
-     (q/begin-shape)
-     (q/vertex 0 0 0)
-     (q/quadratic-vertex 30 0 50 10 0 100)
-     (q/quadratic-vertex 50 0 -50 90 0 100)
-     (q/quadratic-vertex 80 0 50 100 0 0)
-     (q/end-shape :close)))
+(defsnippet quadratic-vertex
+  "quadratic-vertex"
+  {:renderer :p3d}
+
+  (q/camera 50 200 50 50 0 0 0 0 -1)
+  (q/line 0 0 0 0 0 100)
+  (q/line 0 0 0 0 100 0)
+  (q/line 0 0 0 100 0 0)
+  (q/begin-shape)
+  (q/vertex 0 0)
+  (q/quadratic-vertex 30 50 10 100)
+  (q/quadratic-vertex 50 -50 90 100)
+  (q/quadratic-vertex 80 50 100 0)
+  (q/end-shape :close)
+  (q/begin-shape)
+  (q/vertex 0 0 0)
+  (q/quadratic-vertex 30 0 50 10 0 100)
+  (q/quadratic-vertex 50 0 -50 90 0 100)
+  (q/quadratic-vertex 80 0 50 100 0 0)
+  (q/end-shape :close))

 #?(:clj
    (defsnippet texture


more work on overlays

more work on overlays

--- src/cljs/defender_cljs/overlay/core.cljs
+++ src/cljs/defender_cljs/overlay/core.cljs
@@ -14,11 +14,9 @@
 (def top-bound c/hud-height)
 (def bottom-bound (- c/hud-height c/top-overlay-height))

-(def width-segments (/ (- right-bound left-bound)) 7)
-(def inner-left-bound (* 3 width-segments))
-(def inner-right-bound (* 4 width-segments))
-
-
+(def width-segments (/ (- right-bound left-bound) 7))
+(def inner-left-bound (+ left-bound (* 3 width-segments)))
+(def inner-right-bound (+ left-bound (* 4 width-segments)))

 (defn init-hud-outline [scene]
   (let [
@@ -59,14 +57,20 @@
          :color line-color
          :line-width line-width)

-        white-left-bound nil
+        white-left-bound
+        (geo/draw-line
+         [[inner-left-bound top-bound 1]
+          [inner-left-bound bottom-bound 1]]
+         :color 0xffffff
+         :line-width line-width)

         ]

     (.add scene straight-line)
     (.add scene left-line)
     (.add scene right-line)
-    (.add scene top-line)))
+    (.add scene top-line)
+    (.add scene white-left-bound)))

 (def score (text/create-label "000000" {:size 20 :color 0xff00ff}))
 (obj/set-position! score 120 (- c/hud-height c/top-overlay-height


Fixed bug in uniform-string-mutation.

Fixed bug in uniform-string-mutation.

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -209,7 +209,7 @@
         constant-mutator (fn [token]
                            (let [const (:instruction token)]
                              (if (string? const)
-                               (string-tweak const)
+                               (assoc token :instruction (string-tweak const))
                                token)))
         token-mutator (fn [token]
                         (if (< (lrand) uniform-mutation-rate)


Replace the loop for ideal-bitrate with filter and max

--- src/mdr2/encode.clj
+++ src/mdr2/encode.clj
@@ -70,18 +70,16 @@
   "Calculate the ideal bitrate based on the size of a production and
   how much will generally fit on a CD-ROM. It will first try a higher
   bitrate (see `bitrates`). If the production still doesn't fit on one
-  CD it will subsequently try lesser bitrates. Return nil if the
-  content doesn't even fit on one CD with the lowest bitrate."
+  CD it will subsequently try lesser bitrates. Return 0 if the content
+  doesn't even fit on one CD with the lowest bitrate."
   [production]
   (let [dtb (path/recorded-path production)
         duration (quot (dtb/audio-length dtb) 1000) ; convert from millisecs to secs
         sampling-ratio (if (dtb/mono? dtb) 1 2)
         max-bitrate (/ (* (/ max-size duration sampling-ratio) 8) 1000)]
-    (loop [bitrates bitrates]
-      (when-first [bitrate bitrates]
-        (if (> max-bitrate bitrate)
-          bitrate
-          (recur (rest bitrates)))))))
+    (->> bitrates
+         (filter #(<= % max-bitrate))
+         (apply max 0))))

 (defn clean-up
   "Clean up temporary files of a production, namely the mp3 encoded
@@ -121,7 +119,7 @@
   ([{:keys [volumes state] :as production}]
    {:pre [(= state "recorded")]}
    (let [ideal-bitrate (ideal-bitrate production)]
-     (if (and (= volumes 1) ideal-bitrate)
+     (if (and (= volumes 1) (not= ideal-bitrate 0))
        ;; the production has just been recorded, no specific number
        ;; of volumes are required and it fits on one volume
        (encode production ideal-bitrate)


make vm schema mor modular

make vm schema mor modular

--- src/dda/pallet/dda_managed_vm/domain.clj
+++ src/dda/pallet/dda_managed_vm/domain.clj
@@ -26,8 +26,7 @@
              (s/optional-key :password-store-single) s/Str
              (s/optional-key :password-store-multi) s/Str})

-(def DdaVmDomainConfig
-  "The convention configuration for managed vms crate."
+(def DdaVmUser
   {:user {:name s/Str
           :password Secret
           (s/optional-key :email) s/Str
@@ -35,9 +34,18 @@
                                  :ssh-private-key Secret}
           (s/optional-key :gpg) {:gpg-public-key Secret
                                  :gpg-private-key Secret
-                                 :gpg-passphrase Secret}}
-   :type (s/enum :desktop-minimal :desktop-office :remote)
-   (s/optional-key :bookmarks) infra/Bookmarks})
+                                 :gpg-passphrase Secret}}})
+
+(def DdaVmBookmarks
+  {(s/optional-key :bookmarks) infra/Bookmarks})
+
+(def DdaVmDomainConfig
+  "The convention configuration for managed vms crate."
+  (merge
+    DdaVmUser
+    DdaVmBookmarks
+    {:type (s/enum :desktop-minimal :desktop-office :remote)}))
+

 (def DdaVmDomainResolvedConfig
   "The convention configuration for managed vms crate."


fix: handle issue/pull_request object for PRs

- PR comments are issue comments, so the issue object is present in the event
- PR review events instead have a pull_request object

--- src/github_bot_app/action/auto_label.clj
+++ src/github_bot_app/action/auto_label.clj
@@ -6,24 +6,28 @@
 (defn- mark-review-done [payload config]
   (let [owner (get-in payload [:repository :owner :login])
         repo (get-in payload [:repository :name])
-        issue-id (get-in payload [:pull_request :number])
+        ;; support being called from both an issue_comment
+        ;; and pull_request_review payload context
+        pr-obj (or (:issue payload) (:pull_request payload))
+        pr-id (:number pr-obj)
+        pr-url (:url pr-obj)
         {:keys [review-done-remove-labels review-done-add-label]} (:auto-label config)]
    (github-api-time!
            (gh-issues/add-labels
-            owner repo issue-id
+            owner repo pr-id
             [review-done-add-label]
             (:auth-options config)))
    (log/info (pr-str
               {:api-call :add-labels
-               :url (get-in payload [:issue :labels_url])
+               :url pr-url
                :add-labels [review-done-add-label]}))
    (doseq [label review-done-remove-labels]
     (github-api-time!
-      (gh-issues/remove-label owner repo issue-id label
+      (gh-issues/remove-label owner repo pr-id label
        (:auth-options config)))
     (log/info (pr-str
                {:api-call :remove-label
-                :url (get-in payload [:issue :labels_url])
+                :url pr-url
                 :remove-label label})))))

 (defn run-action [event payload config]
@@ -48,6 +52,9 @@

    (= event
       "issue_comment")
+   ;; https://developer.github.com/v3/issues/#get-a-single-issue
+   ;; Note: In the past, pull requests and issues were more closely aligned than they are now. As far as the API is concerned, every pull request is an issue, but not every issue is a pull request.
+   ;; This endpoint may also return pull requests in the response. If an issue is a pull request, the object will include a pull_request key.
    (when (get-in payload [:issue :pull_request])
      (let [issue-user (get-in payload [:issue :user :login])
            comment-user (get-in payload [:comment :user :login])


Add project_code to search fields

Add project_code to search fields

--- src/kixi/hecuba/data/entities/search.clj
+++ src/kixi/hecuba/data/entities/search.clj
@@ -42,13 +42,14 @@

 (defn project-search-fields [entity db-session]
   (let [project_id (:project_id entity)
-        {:keys [name organisation type_of programme_id]} (projects/get-by-id db-session project_id)]
+        {:keys [name organisation type_of programme_id project_code]} (projects/get-by-id db-session project_id)]
     (-> entity
         (assoc :programme_id programme_id)
         (assoc-in [:full_entity :programme_id] programme_id)
         (assoc-in [:full_entity :project_name] name)
         (assoc :type_of type_of)
         (assoc :project_name name)
+        (assoc :project_code project_code)
         (assoc :project_organisation organisation))))

 ;; TOFIX Some projects didn't have programme_id. Not sure if it's just a local issue.


[sway] )

[sway] )

--- src/ombs/db/old.clj
+++ src/ombs/db/old.clj
@@ -161,9 +161,7 @@
   ([eid]
    (= (statuses :initial)
       (:status (first (sql/select events (sql/fields :status)
-                                  (sql/where {:id eid} ) )))))
-
-  )
+                                  (sql/where {:id eid} )))))))

 (defn event-from-fee [fid]
   (first (sql/select events


fix q15

fix q15

--- src/puzzule/q15.clj
+++ src/puzzule/q15.clj
@@ -1,15 +1,18 @@
-(ns puzzule.q15
-  (:require [clojure.math.combinatorics :as combo]))
+(ns puzzule.q15)

 (def n 10)
 (def steps 4)

-(defn move [a b cnt]
+(defn move-pares [max-num]
+  (for [i (range 1 (inc max-num))
+        j (range 1 (inc max-num))] [i j]))
+
+(defn move [steps a b cnt]
   (cond
     (> a b) 0
     (= a b) 1
     :else (+ cnt
-             (reduce + (map (fn [n] (apply #(move (+ a %) (- b %) cnt) n))
-                            [[1 1] [1 2] [1 3] [1 4] [2 1] [2 2] [2 3] [2 4] [3 1] [3 2] [3 3] [3 4] [4 1] [4 2] [4 3] [4 4]])))))
+             (reduce + (map (fn [move-pare] (apply #(move steps (+ a %1) (- b %2) cnt) move-pare))
+                            (move-pares steps))))))

-(move 0 n 0)
+(move steps 0 n 0)


Using PApplet/runSketch for start sketch. Remove :exit-on-close option.

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -28,8 +28,6 @@
   It means we can dispose frame, call on-close function and perform other
   clean ups."
   [applet]
-  (when-let [frame @(:target-obj (meta applet))]
-    (.dispose frame))
   ((:on-close (meta applet))))

 (defn applet-stop
@@ -58,18 +56,22 @@
   (applet-safe-exit applet)
   (javax.swing.SwingUtilities/invokeLater
     (fn []
-      (when-let [frame @(:target-obj (meta applet))]
-        (.hide frame)))))
-
-(defn- launch-applet-frame
+      (when-let [frame (. applet frame)]
+        (.setVisible frame false)))))
+
+
+(defn- prepare-applet-frame
   [applet title renderer keep-on-top?]
   (let [truthify       #(not (or (nil? %) (false? %)))
         keep-on-top?   (truthify keep-on-top?)
         m              (.meta applet)
         close-op       JFrame/DO_NOTHING_ON_CLOSE
-        f              (JFrame. title)
-        falsify        #(not (or (nil? %) (true? %)))
-        decor?         (falsify (:decor m))]
+        f              (. applet frame)
+        falsify        #(not (or (nil? %) (true? %)))]
+
+    (doseq [listener (.getWindowListeners f)]
+      (.removeWindowListener f listener))
+
     (doto f
       (.addWindowListener  (reify WindowListener
                              (windowActivated [this e])
@@ -80,25 +82,28 @@
                              (windowIconified [this e])
                              (windowOpened [this e])
                              (windowClosed [this e])))
-      (.setUndecorated decor?)
-      (.setDefaultCloseOperation close-op)
-      (.add applet)
-      (.pack))
+      (.setDefaultCloseOperation close-op))
+
+    (javax.swing.SwingUtilities/invokeLater
+     (fn []
+       (.setResizable f true)
+       (.setAlwaysOnTop f keep-on-top?)))
+
     (when (= renderer :opengl)
       (.setResizable f false))
-    (.show f)
-    (.setAlwaysOnTop f keep-on-top?)
     (reset! (:target-obj (meta applet)) f)
     applet))
+

 (defn- applet-run
   "Launches the applet to the specified target."
   [applet title renderer target]
+  (PApplet/runSketch (into-array String ["--hide-stop" title]) applet)
   (case target
-    :frame (launch-applet-frame applet title renderer false)
-    :perm-frame (launch-applet-frame applet title renderer true)
-    :none applet)
-  (.init applet))
+    :frame (prepare-applet-frame applet title renderer false)
+    :perm-frame (prepare-applet-frame applet title renderer true)
+    :none (prepare-applet-frame applet title renderer false)))
+

 (def ^{:private true}
   renderer-modes {:p2d    PApplet/P2D
@@ -113,11 +118,6 @@
   This string can be passed to native Processing methods."
   [renderer]
   (resolve-constant-key renderer renderer-modes))
-(defn- hide-menu-bar-if-macos []
-  (when (= PApplet/platform PApplet/MACOSX)
-    (.. (Class/forName "japplemenubar.JAppleMenuBar")
-        (getDeclaredMethod "hide" (into-array Class []))
-        (invoke nil (into-array Object [])))))

 (defn- display-size
   "Returns size of screen. If there are 2 or more screens it probably return size of
@@ -201,14 +201,17 @@
                     frameRate frameRateParent
                     mouseReleased mouseReleasedParent
                     focusLost focusLostParent
-                    noLoop noLoopParent})
+                    noLoop noLoopParent
+                    sketchFullScreen sketchFullScreenParent})
+
+(defn -sketchFullScreen [this] false)

 (defn -quil-applet-init [state]
   [[] state])

 (defn -quil-applet-post-init [this _]
-  (let [[width height] (:size (.state this))]
-    (.setPreferredSize this (Dimension. width height))))
+  (let [[width height] (:size (meta this))]
+    (.resize this width height)))

 (defn -meta [this]
   (.state this))
@@ -220,10 +223,10 @@
   ; (don't know why, but let's trust Processing guys).
   ; Technically it's not first (there are 'when' and 'let' before 'size'),
   ; but hopefully it will work fine.
-  (when (= (:renderer (meta this)) :pdf)
-    (let [[width height] (:size (meta this))
+  (let [[width height] (:size (meta this))
           renderer (resolve-renderer (:renderer (meta this)))
           file (-> this meta :output-file absolute-path)]
+    (when (= (:renderer (meta this)) :pdf)
       (.size this (int width) (int height) renderer file)))
   (with-applet this
     ((:setup-fn (meta this)))))
@@ -345,13 +348,11 @@

    :on-close       - Called once, when sketch is closed"
   [& opts]
-  (when (= :fullscreen (:size opts))
-    (hide-menu-bar-if-macos))
   (let [options           (merge {:size [500 300]
                                   :target :frame
                                   :safe-draw-fn true}
                                  (apply hash-map opts))
-        decor             (:decor opts (not= :fullscreen (:size options)))
+
         size              (process-size (:size options))
         target            (validate-target! (:target options))
         title             (or (:title options) (str "Quil " (swap! untitled-applet-id* inc)))
@@ -366,12 +367,7 @@
                                 (Thread/sleep 1000))))
         draw-fn           (if (:safe-draw-fn options) safe-draw-fn draw-fn)

-        on-close-fn       (let [close-fn (or (:on-close options) no-fn)]
-                            (if (true? (:exit-on-close options))
-                              (fn []
-                                  (close-fn)
-                                  (System/exit 0))
-                              close-fn))
+        on-close-fn       (or (:on-close options) no-fn)

         state             (atom nil)
         target-obj        (atom nil)
@@ -388,8 +384,7 @@
                                   :draw-fn draw-fn
                                   :renderer renderer
                                   :size size
-                                  :target-frame-rate (atom 60)
-                                  :decor decor}
+                                  :target-frame-rate (atom 60)}
                                  listeners)
         prx-obj           (quil.Applet. applet-state)]
     (doto prx-obj


Add fullscreen 'support'.

Add fullscreen 'support'.

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -118,13 +118,25 @@
   [renderer]
   (resolve-constant-key renderer renderer-modes))

-(defn- validate-size!
+
+(defn- display-size
+  "Returns size of screen. If there are 2 or more screens it probably return size of
+  default one whatever it means."
+  []
+  (let [bounds (.. (java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment)
+                   getDefaultScreenDevice
+                   getDefaultConfiguration
+                   getBounds)]
+    [(.-width bounds) (.-height bounds)]))
+
+(defn- process-size
   "Checks that the size vector is exactly two elements. If not, throws
   an exception, otherwise returns the size vector unmodified."
   [size]
-  (when-not (= 2 (count size))
-    (throw (IllegalArgumentException. (str "Invalid size vector:" size ". Was expecting only 2 elements: [x-size y-size]. To specify renderer, use :renderer key."))))
-  size)
+  (cond (= size :fullscreen) (display-size)
+        (and (coll? size) (= 2 (count size))) size
+        :else (throw (IllegalArgumentException.
+                      (str "Invalid size definition:" size ". Was expecting :fullscreen or 2 elements vector: [x-size y-size].")))))

 (def ^{:private true} VALID-TARGETS #{:frame :perm-frame :none})

@@ -349,7 +361,7 @@
                                   :target :frame
                                   :safe-draw-fn true}
                                  (apply hash-map opts))
-        size              (validate-size! (:size options))
+        size              (process-size (:size options))
         target            (validate-target! (:target options))
         title             (or (:title options) (str "Quil " (swap! untitled-applet-id* inc)))
         renderer          (or (:renderer options) :java2d)
@@ -377,6 +389,7 @@
                                   :setup-fn setup-fn
                                   :draw-fn draw-fn
                                   :renderer renderer
+                                  :size size
                                   :target-frame-rate (atom 60)}
                                  listeners)
         prx-obj           (quil.Applet. applet-state)


Added more optional metadata to the page header template.

--- lambda-blog/src/lambda_blog/templates/page.clj
+++ lambda-blog/src/lambda_blog/templates/page.clj
@@ -19,9 +19,18 @@
                     :href (link-or-pathcat path-to-root %)})
        stylesheets))

+(defn- metadata [ent & keys]
+  (reduce (fn [m k]
+            (if-let [v (get ent k)]
+              (cons (html/meta {:name k :content v})
+                    m)
+              m))
+          ()
+          keys))
+
 (defn header
   "Creates an HTML `head` element containing various metadata, `scripts` & `stylesheets`."
-  [{:keys [favicon feed path-to-root scripts stylesheets title]}]
+  [{:keys [favicon feed path-to-root scripts stylesheets title] :as ent}]
   (html/head (html/meta {:charset :utf-8})
              (html/title title)
              (css path-to-root stylesheets)
@@ -36,7 +45,8 @@
              (html/meta {:name :viewport
                          :content "width=device-width, initial-scale=1.0"})
              (html/meta {:name :generator
-                         :content (str "λ-blog v." (get-version))})))
+                         :content (str "λ-blog v." (get-version))})
+             (metadata ent :description :keywords :author)))

 (defn banner
   "Creates a page banner `header` using configured `banner-template`."


Remove save-trip-reports! since scrape-trs is now a library.

--- project/scrape-trs/src/scrape_trs/core.clj
+++ project/scrape-trs/src/scrape_trs/core.clj
@@ -24,7 +24,3 @@
                           trip-report-urls
                           (map slurp trip-report-urls))]
     trip-reports))
-
-(defn save-trip-reports!
-  ""
-  [f trip-reports])


Only work with balanced rule sets for validation

--- src/themis/core.clj
+++ src/themis/core.clj
@@ -65,7 +65,8 @@
   "Create a lazy sequence of validating a given data structure
   against the a normalized validation query vector/seq"
   [t normalized-query]
-  (map #(validate-vec t %) normalized-query))
+  (when (query/balanced? normalized-query)
+    (map #(validate-vec t %) normalized-query)))

 (defn validation
   "Validate a data structure, `t`,


spec voke.clock

spec voke.clock

--- src/voke/clock.cljs
+++ src/voke/clock.cljs
@@ -1,11 +1,13 @@
 (ns voke.clock
   "A system for tracking the amount of sim time (as opposed to wall time) that's elapsed."
-  (:require [schema.core :as s])
-  (:require-macros [schema.core :as sm]))
+  (:require [cljs.spec :as s]))

 (defonce ^:private clock (atom 0))

 (defn now [] @clock)

-(sm/defn add-time! [dt :- s/Num]
+(defn add-time! [dt]
   (swap! clock + dt))
+
+(s/fdef add-time!
+  :args (s/cat :dt number?))


Adds verification of required Kafka config

--- src/yuubin/core.clj
+++ src/yuubin/core.clj
@@ -15,11 +15,12 @@
                          java.io.PushbackReader.)]
     (clojure.edn/read reader)))

+(def required-keys
+  [:mailbox :api-key :template-dir :bootstrap-servers :incoming-topic :receipt-topic])
+
 ;; Ensure required fields are set, and default port to 3000 if not provided.
 (defn- verify-config [conf]
-  {:pre [(contains? conf :mailbox)
-         (contains? conf :api-key)
-         (contains? conf :template-dir)]}
+  {:pre [(every? conf required-keys)]}
   (merge {:port 3000} conf))

 (defn- ring-handler [mail-handler]
@@ -44,7 +45,6 @@
     (.setDaemon true)
     (.start)))

-;; TODO Require :bootstrap-servers and :incoming-topic to be in config.
 (defn- monitor-queue [config mail-handler]
   (let [consumer-config (merge kafka/default-consumer-config {"bootstrap.servers" (:bootstrap-servers config)})
         consumer (kafka/consumer consumer-config (:incoming-topic config))]


Print update log only if actually updating the DB.

--- src/oc/storage/resources/maintenance.clj
+++ src/oc/storage/resources/maintenance.clj
@@ -9,8 +9,8 @@

 (defn- update-entry [conn entry original-entry dry-run]
   (schema/validate common/Entry entry)
-  (timbre/info "--> Updating entry from" (count (:shared original-entry)) "to" (count (:shared entry)))
   (when-not dry-run
+    (timbre/info "--> Updating entry from" (count (:shared original-entry)) "to" (count (:shared entry)))
     (db-common/update-resource conn common/entry-table-name :uuid original-entry entry (db-common/current-timestamp))))

 (schema/defn ^:always-validate shared-dedup-and-limit-for-entry!


Focus management #38 - non-focusable component to trigger focus movent into approproate recepient when clicked (e.g. label on window surface, non-focusable spinner buttons, etc.)

--- flatguicore/src/flatgui/focus.clj
+++ flatguicore/src/flatgui/focus.clj
@@ -107,12 +107,18 @@
 (def clean-state {:mode :none
                   :focused-child nil})

-(def having-focus-state {:mode :has-focus
-                         :focused-child nil})
-
-(defn temporarily-taken-from-state [permanent-owner-child dir] {:mode :has-focus
-                                                                :focused-child permanent-owner-child
-                                                                :throw-mode dir})
+(defn having-focus-state [component comment]
+  (do
+    (fg/log-debug "Permanent focus (" comment ") received by" (:id component))
+    {:mode :has-focus
+     :focused-child nil}))
+
+(defn temporarily-taken-from-state [component comment permanent-owner-child dir]
+  (do
+    (fg/log-debug "Temporary focus (" comment ") from" permanent-owner-child "received by" (:id component))
+    {:mode :has-focus
+     :focused-child permanent-owner-child
+     :throw-mode dir}))

 (defn focus-child [child-id]
   (if (keyword? child-id)
@@ -124,10 +130,14 @@
 (defn focus-child-by-direction [child-id dir]
   (assoc (focus-child child-id) :throw-mode dir))

+(defn focus-uninterested? [component]
+  (and (not (:closed-focus-root component)) (not (:focusable component))))
+
 (fg/defevolverfn :focus-state
   (let [reason (fg/get-reason)
         this-focused-child (:focused-child old-focus-state)
         this-mode (:mode old-focus-state)
+        parent-id (get-property [] :id)
         parent-focus-state (get-property [] :focus-state)
         parent-focused-child (:focused-child parent-focus-state)
         parent-mode (:mode parent-focus-state)]
@@ -153,7 +163,10 @@
         {:mode :requests-focus
          :focused-child this-focused-child}
         (and (:closed-focus-root component) (#{:none :throws-focus :requests-focus} this-mode))
-        having-focus-state
+        (having-focus-state component "closed root by mouse")
+        (focus-uninterested? component)
+        {:mode :got-trigger
+         :focused-child nil}
         :else old-focus-state)

       (fgc/parent-reason? reason)
@@ -162,9 +175,15 @@
         ;; Otherwise my parent has focus permanently and my state is clean
         :has-focus (if (= parent-focused-child (:id component)) ; This condition means that parent has focus temporarily
                      ;; Parent keeps latest throwing direction in :throw-mode in this case. Track it for further use
-                     (assoc having-focus-state :throw-mode (:throw-mode parent-focus-state))
+                     (assoc (having-focus-state component (str "from parent " parent-id " that kept temporary")) :throw-mode (:throw-mode parent-focus-state))
                      clean-state)
-        ;:has-focus clean-state
+        :got-trigger (if (= this-mode :got-trigger)
+                       clean-state
+                       (if (:focusable component)
+                         having-focus-state
+                         (if-let [child-id (get-in-cycle component :first nil)]
+                           (focus-child-by-direction child-id :next)
+                           old-focus-state)))
         :none clean-state
         :parent-of-focused (if (= parent-focused-child (:id component))
                              ;; If my parent is :parent-of-focused and I am :parent-of-focused,
@@ -190,7 +209,7 @@
                                                          :first)
                                                        nil)))]
                                  (focus-child-by-direction child-id (:throw-mode parent-focus-state))
-                                 having-focus-state)
+                                 (having-focus-state component (str "from parent " parent-id " that requested")))
                                ;; No change in state but track focus movent direction
                                (assoc old-focus-state :throw-mode (:throw-mode parent-focus-state)))

@@ -238,6 +257,7 @@

                             ;; My child request focus and I throw focus - then I let this child get focus
                             :throws-focus (focus-child child-id))
+
           :throws-focus (case child-throw-mode
                           ;; My child throws focus in :prev direction. Give focus to previous child.
                           ;; But if I'm not a closed root then there may be no previous child,
@@ -247,7 +267,7 @@
                                     ;; My child throws focus, but there is no other component to take it.
                                     ;; So I take it temporarily and child will take back within the next step. (*2)
                                     ;; Latest movement direction is tracked to be used within the next step
-                                    (temporarily-taken-from-state this-focused-child :prev)
+                                    (temporarily-taken-from-state component (str "prev, reason: " child-id) this-focused-child :prev)
                                     (focus-child-by-direction prev-child :prev))
                                   {:mode :throws-focus
                                    :throw-mode :prev
@@ -261,7 +281,7 @@
                                     ;; My child throws focus, but there is no other component to take it.
                                     ;; So I take it temporarily and child will take back within the next step. (*2)
                                     ;; Latest movement direction is tracked to be used within the next step
-                                    (temporarily-taken-from-state this-focused-child :next)
+                                    (temporarily-taken-from-state component (str "next, reason: " child-id) this-focused-child :next)
                                     (focus-child-by-direction next-child :next))
                                   {:mode :throws-focus
                                    :throw-mode :next
@@ -279,7 +299,22 @@
                                               :throw-mode (if (:closed-focus-root component)
                                                             :next
                                                             :out-of-cycle-next)
-                                              :focused-child this-focused-child})))
+                                              :focused-child this-focused-child})
+
+          :got-trigger (cond
+                         (:focusable component)
+                         (having-focus-state component "trigger")
+                         (or
+                           (:closed-focus-root component)
+                           (get-in-cycle component :first nil))
+                         (temporarily-taken-from-state component "trigger"      ;TODO This worked nicely even with tester widged but broke slider
+                           (if-let [first-to-give (get-in-cycle component :first nil)]
+                              first-to-give
+                              child-id)
+                           nil)
+                         :else
+                         {:mode :got-trigger
+                          :focused-child nil})))

       :else ; Neither event type - ignore
       old-focus-state)))


add authentication to GET /api/forms (#245)

--- server/src/spacon/components/form/core.clj
+++ server/src/spacon/components/form/core.clj
@@ -17,10 +17,12 @@

 (defn http-get-all-forms
   "Returns the latest version of each form"
-  [_]
-  ;; todo: get all the forms for all the teams that the calling user belongs to
-  (log/debug "Getting all forms")
-  (response/ok (formmodel/all)))
+  [request]
+  (let [user (get-in request [:identity :user])
+        team-ids (map :id (:teams user))]
+    (log/debugf "Getting all forms for %s" (:email user))
+    (response/ok (filter #(> (.indexOf team-ids (:team-id %)) -1)
+                         (formmodel/all)))))

 (defn http-get-form
   "Gets the latest version of a form by its form-key"
@@ -150,7 +152,7 @@
     (formmodel/add-form-data form-data form-id device-identifier)))

 (defn- routes [mqtt]
-  #{["/api/forms"                :get    (conj common-interceptors `http-get-all-forms)]
+  #{["/api/forms"                :get    (conj common-interceptors check-auth `http-get-all-forms)]
     ["/api/forms"                :post   (conj common-interceptors check-auth (partial http-post-form mqtt)) :route-name :create-form]
     ["/api/forms/:form-key"      :delete (conj common-interceptors check-auth (partial http-delete-form-by-key mqtt)) :route-name :delete-form]
     ["/api/forms/:form-key"      :get    (conj common-interceptors check-auth `http-get-form)]


make current nav menu selection 'active'.

--- src-cljs/kixi/hecuba/menu.cljs
+++ src-cljs/kixi/hecuba/menu.cljs
@@ -22,8 +22,10 @@
        [:div
         [:ul {:class "nav navbar-nav"}
          (for [{:keys [pathname text roles]} menu
-               :let [href (if (= page-pathname pathname) "#" pathname)]]
-           [:li [:a {:href href} text]])]
+               :let [current-page? (= page-pathname pathname)
+                     href (if current-page? "#" pathname)
+                     opts (when current-page? {:class "active"})]]
+           [:li opts [:a {:href href} text]])]
         [:div.pull-right {:id :whoami} (slugs/slugify-whoami whoami)]]))))


missing go-block

missing go-block

--- rn-app/src/cljs/meo/ios/store.cljs
+++ rn-app/src/cljs/meo/ios/store.cljs
@@ -4,6 +4,7 @@
             [glittershark.core-async-storage :as as]
             [clojure.data.avl :as avl]
             [meo.ios.sync :as sync]
+            [cljs.tools.reader.edn :as edn]
             [cljs.core.async :refer [<!]]))

 (defn persist [{:keys [current-state put-fn msg-payload]}]
@@ -114,7 +115,7 @@

 (defn set-secrets [{:keys [current-state msg-payload]}]
   (let [new-state (assoc-in current-state [:secrets] msg-payload)]
-    ;(<! (as/set-item :secrets msg-payload))
+    (go (<! (as/set-item :secrets msg-payload)))
     {:new-state new-state}))

 (defn state-fn [put-fn]


Doc arities taking maps as first param

Doc arities taking maps as first param

--- scheduling/src/immutant/scheduling.clj
+++ scheduling/src/immutant/scheduling.clj
@@ -134,46 +134,46 @@
         (.stop scheduler)))
     stopped?))

-(defoption ^{:arglists '([n] [kw] [n kw & n-kws])} in
+(defoption ^{:arglists '([n] [kw] [m v] [n kw & n-kws] [m n kw & n-kws])} in
   "Specifies the period after which the job will fire, in
   milliseconds, a period keyword, or multiplier/keyword pairs, e.g.
   `(in 5 :minutes 30 :seconds)`. See [[every]] for the list of valid
    period keywords. See [[schedule]].")

-(defoption ^{:arglists '([date] [ms] [HHmm])} at
+(defoption ^{:arglists '([date] [ms] [HHmm] [m v])} at
   "Takes a time after which the job will fire, so it will run
   immediately if the time is in the past; can be a `java.util.Date`,
   millis-since-epoch, or a String in `HH:mm` format. See
   [[schedule]].")

-(defoption ^{:arglists '([n] [kw] [n kw & n-kws])} every
+(defoption ^{:arglists '([n] [kw] [m v] [n kw & n-kws] [m n kw & n-kws])} every
   "Specifies a period between function calls, in milliseconds, a
   period keyword, or multiplier/keyword pairs, e.g.
   `(every 1 :hour 20 :minutes)`.  Both singular and plural versions of
   :second, :minute, :hour, :day, and :week are valid period keywords.
   See [[schedule]].")

-(defoption ^{:arglists '([date] [ms] [HHmm])} until
+(defoption ^{:arglists '([date] [ms] [HHmm] [m v])} until
   "When [[every]] is specified, this limits the invocations by time;
   can be a `java.util.Date`, millis-since-epoch, or a String in
   `HH:mm` format, e.g. `(-> (every :hour) (until \"17:00\"))`. When
   combined with [[limit]], whichever triggers first ends the
   iteration. See [[schedule]].")

-(defoption ^{:arglists '([n])} limit
+(defoption ^{:arglists '([n] [m n])} limit
   "When [[every]] is specified, this limits the invocations by count,
   including the first one, e.g. `(-> (every :hour) (limit 10))`. When
   combined with [[until]], whichever triggers first ends the
   iteration. See [[schedule]].")

-(defoption ^{:arglists '([str])} cron
+(defoption ^{:arglists '([str] [m str])} cron
   "Takes a Quartz-style cron spec, e.g. `(cron \"0 0 12 ? * WED\")`,
    see the [Quartz docs](http://quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-06)
    for the syntax. See [[schedule]].")

-(defoption ^{:arglists '([boolean])} singleton
+(defoption ^{:arglists '([boolean] [m boolean])} singleton
   "If true (the default), only one instance of a given job name will
    run in a cluster. See [[schedule]].")

-(defoption ^{:arglists '([str])} id
+(defoption ^{:arglists '([str] [m str])} id
   "Takes a String or keyword to use as the unique id for the job. See [[schedule]].")


Cannibalize home page tool support for /features

--- src-cljs/frontend/components/features.cljs
+++ src-cljs/frontend/components/features.cljs
@@ -1,9 +1,11 @@
 (ns frontend.components.features
   (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer close!]]
             [clojure.string :as str]
+            [frontend.async :refer [raise!]]
             [frontend.components.common :as common]
             [frontend.components.plans :as plans-component]
             [frontend.components.shared :as shared]
+            [frontend.components.landing :as landing]
             [frontend.state :as state]
             [frontend.stefon :as stefon]
             [frontend.utils :as utils :include-macros true]
@@ -25,6 +27,57 @@
                  "clojure-2"
                  "java-2"
                  "php-2"]))
+
+(defn practice [app owner]
+  (reify
+    om/IDisplayName (display-name [_] "Home Practice")
+    om/IRender
+    (render [_]
+      (let [selected-customer (get-in app state/customer-logo-customer-path :shopify)
+            selected-toolset (get-in app state/selected-toolset-path :languages)]
+        (html
+         [:section
+          (let [hovered-customer (om/get-state owner [:hovered-customer])
+                tools (get-in landing/customer-brands [hovered-customer :tools] #{})]
+            [:div.container-fluid
+             [:div.row
+              [:div.col-xs-4.col-xs-offset-4
+               [:div.practice-tools
+                [:article
+                 (for [[toolset template] landing/supported-tools]
+                   (html ; use html in for loops for perf
+                         [:div.supported-tools {:class (when (= selected-toolset toolset) "active")}
+                          [:div.supported-tools-upper
+                           (for [tool (:upper template)]
+                             (html
+                               [:div.supported-tool {:class (when (contains? tools tool) "hover")
+                                                     :alt (name tool)}
+                                [:figure
+                                 [:svg {:class (str "tool-logo-" (name tool))
+                                        :x "0" :y "0" :view-box "0 0 100 100"}
+                                  [:path {:d (get landing/tools-logos tool)}]]]]))]
+                          [:div.supported-tools-lower
+                           (for [tool (:lower template)]
+                             (html
+                               [:div.supported-tool {:class (when (contains? tools tool) "hover")
+                                                     :alt (name tool)}
+                                [:figure
+                                 [:svg {:class (str "tool-logo-" (name tool))
+                                        :x "0" :y "0" :view-box "0 0 100 100"}
+                                  [:path {:d (get landing/tools-logos tool)}]]]]))]]))]]]]])
+
+          [:div.practice-articles
+           [:article
+            [:h2.text-center "Devs rely on us to just work; we support the right tools."]
+            [:p
+             (for [toolset ["Languages" "databases" "queues" "browsers" "deployment"]]
+               (html
+                [:span [:a {:on-mouse-enter #(raise! owner [:toolset-clicked {:toolset (keyword (str/lower-case toolset))}])} toolset] ", "]))
+             "we support all of your tools.
+              If it runs on Linux, then it will work on CircleCI.
+              We'll even be around to help you install your own tools.
+              The best development teams in the world trust us as their continuous integration and delivery solution because of our unmatched support and our ability to scale with them.
+              We're built for teams."]]]])))))

 (defn testimonial
   [{:keys [company-name company-short customer-quote employee-name employee-title]}]
@@ -229,13 +282,9 @@
      [:div.outer-section
       [:section.container
        [:div.row
-        [:div.col-xs-12
-         [:h2.text-center
-          "Devs rely on us to just work. CircleCI supports your technology stack."
-          [:br]
-          [:small "Languages, Databases, Queus, Browsers, Deployment; we support all of your tools. The best teams in the world trust us as their continuous integration and delivery partner because of our unmatched support and flexibility."]]]]
-       [:div.row]]]
-     [:div.outer-section
+        [:div.col-xs-10.col-xs-offset-1
+         (om/build practice app)]]]]
+     [:div.outer-section.outer-section-condensed
       [:section.container
        [:div.col-xs-12
         [:h2.text-center "Build better code. Start shipping faster."]


more explicit methods for deciding whether to pass bracket tags to emoji-view method

--- src/chat/client/views/new_message.cljs
+++ src/chat/client/views/new_message.cljs
@@ -77,9 +77,11 @@
                         (string/replace text pattern (str k " ")))
                       :html
                       (fn []
-                        (om/build emoji-view (if (= "(" (first text))
-                                                 (str "(" (apply str (rest (butlast k))) ")")
-                                                  k)
+                        (om/build emoji-view (let [show-brackets? (= "(" (first text))
+                                                   emoji-name (apply str (-> k rest butlast))]
+                                               (if (true? show-brackets?)
+                                                 (str "(" emoji-name ")")
+                                                 k))
                                   {:react-key k}))}))))))

    ; ... @<user>  -> autocompletes user name


when-let a (seq) for efficiency

when-let a (seq) for efficiency

--- src/clj/com/climate/claypoole/lazy.clj
+++ src/clj/com/climate/claypoole/lazy.clj
@@ -50,7 +50,8 @@
   (lazy-seq
     (let [sprime (try
                    ;; force one element of s to make exceptions happen here
-                   (when (seq s) (cons (first s) (rest s)))
+                   (when-let [s (seq s)]
+                     (cons (first s) (rest s)))
                    (catch Throwable t
                      (f)
                      (throw t)))]


fixup

fixup

--- src/cljs/hacker_agent/hacker-base.cljs
+++ src/cljs/hacker_agent/hacker-base.cljs
@@ -1,7 +1,8 @@
 (ns hacker-agent.hacker-base
   (:require-macros [cljs.core.async.macros :refer [go go-loop]])
   (:require [reagent.core :as reagent :refer [atom]]
-            [cljs.core.async :as async :refer [put! chan <! >! close! merge mult tap]]))
+            [cljs.core.async :as async :refer [put! chan <! >! close! merge mult tap]]
+            [hacker-agent.utils :as utils :refer [dissoc-in]]))

 (defonce url "https://hacker-news.firebaseio.com/v0")


Item-cache-fn allows a limit on bound items stored

--- src/cljs/hacker_agent/hacker-base.cljs
+++ src/cljs/hacker_agent/hacker-base.cljs
@@ -88,13 +88,20 @@
       :value nil
       (.log js/console (clj->js [event key val])))))

-(defn item-cache-fn [data path]
-  (fn [id]
-    (let [child-path (conj path id)]
-      (when-not (get-in @data child-path)
-        (bind! data child-path
-               (id->fbref id)
-               story-binder)))))
+(defn item-cache-fn
+  ([data path]
+   (item-cache-fn data path 0))
+  ([data path limit]
+   (fn [id]
+     (let [cached (get-in @data path)
+           child-path (conj path id)]
+       (when-not (get-in @data child-path)
+         (when (and (> limit 0)
+                    (>= (count cached) limit))
+           (unbind! data (conj path (key (first cached)))))
+         (bind! data child-path
+                (id->fbref id)
+                story-binder))))))

 (defn stories-binder [f]
   (fn [data path msg]


Added helper functions for retrieving information about an entity's key object.

--- src/appengine_magic/services/datastore.clj
+++ src/appengine_magic/services/datastore.clj
@@ -586,3 +586,18 @@
                 :else
                 (KeyFactory/createKey kind (coerce-key-value-type obj)))]
        (get-key-str-helper key))))
+
+
+(defn key-id [entity]
+  (when entity
+    (.getId (get-key-object entity))))
+
+
+(defn key-name [entity]
+  (when entity
+    (.getName (get-key-object entity))))
+
+
+(defn key-kind [entity]
+  (when entity
+    (.getKind (get-key-object entity))))


Remove accordion-panel component.

Remove accordion-panel component.

--- src/cljs/hatnik/web/client/components.cljs
+++ src/cljs/hatnik/web/client/components.cljs
@@ -3,31 +3,6 @@
             [om.dom :as dom :include-macros true]
             [hatnik.web.client.app-state :as state])
   (:use [jayq.core :only [$]]))
-
-
-(defn accordion-panel [& {:keys [body-id header button body]}]
-  (dom/div
-   #js {:className "panel panel-default panel-primary"}
-   (dom/div
-    #js {:className "panel-heading"}
-    (dom/div
-     nil
-     (dom/h4
-      #js {:className "panel-title"}
-      (dom/div #js {:className "row"}
-               (dom/div #js {:className "col-sm-8 col-md-8 col-lg-8"}
-                        (dom/a
-                         #js {:data-parent "#accrodion"
-                              :data-toggle "collapse"
-                              :href (str "#" body-id)}
-                         header))
-               (dom/div
-                #js {:className "col-sm-2 col-md-1 col-lg-1 pull-right"}
-                button)))))
-   (dom/div #js {:className "panel-collapse collapse in"
-                 :id body-id}
-            (dom/div #js {:className "panel-body"}
-                     body))))

 (defn render-action-type [a-type]
   (when (= "email" a-type)
@@ -104,11 +79,28 @@
   (reify
     om/IRender
     (render [_]
-      (accordion-panel
-       :header (dom/div #js {:className "bg-primary"} (get prj "name"))
-       :button (project-header-menu-button prj)
-       :body (actions-table (get prj "id") (get prj "actions"))
-       :body-id (str "__PrjList" (get prj "id"))))))
+      (dom/div
+       #js {:className "panel panel-default panel-primary"}
+       (dom/div
+        #js {:className "panel-heading"}
+        (dom/div
+         nil
+         (dom/h4
+          #js {:className "panel-title"}
+          (dom/div #js {:className "row"}
+                   (dom/div #js {:className "col-sm-8 col-md-8 col-lg-8"}
+                            (dom/a
+                             #js {:data-parent "#accrodion"
+                                  :data-toggle "collapse"
+                                  :href (str "#" (str "__PrjList" (get prj "id")))}
+                             (dom/div #js {:className "bg-primary"} (get prj "name"))))
+                   (dom/div
+                    #js {:className "col-sm-2 col-md-1 col-lg-1 pull-right"}
+                    (project-header-menu-button prj))))))
+       (dom/div #js {:className "panel-collapse collapse in"
+                     :id (str "__PrjList" (get prj "id"))}
+                (dom/div #js {:className "panel-body"}
+                         (actions-table (get prj "id") (get prj "actions"))))))))

 (defn project-list [data owner]
   (reify


"acc" => "prev"

"acc" => "prev"

--- src/cljx/jamesmacaulay/zelkova/signal.cljx
+++ src/cljx/jamesmacaulay/zelkova/signal.cljx
@@ -110,10 +110,10 @@
   [f base source]
   (impl/make-signal {:init-fn (constantly base)
                      :sources [source]
-                     :msg-fn (fn [_event acc [message]]
+                     :msg-fn (fn [_event prev [message]]
                                (when (impl/fresh? message)
                                  (impl/fresh (f (impl/value message)
-                                                  (impl/value acc)))))}))
+                                                (impl/value prev)))))}))

 (defn drop-repeats
   "Returns a signal which relays values of `sig`, but drops repeated equal values."
@@ -135,7 +135,7 @@
   ([f source] (reducep f (f) source))
   ([f init source]
    (->> source
-        (foldp (fn [val acc] (f acc val)) init)
+        (foldp (fn [val prev] (f prev val)) init)
         drop-repeats)))

 (defn transducep


Add missing import on restfull handler.

Add missing import on restfull handler.

--- src/clojure/catacumba/handlers/restful.clj
+++ src/clojure/catacumba/handlers/restful.clj
@@ -32,6 +32,7 @@
            ratpack.handling.Context
            ratpack.handling.ByMethodSpec
            ratpack.handling.Chain
+           ratpack.func.Block
            ratpack.registry.Registry))

 (defn- noop-handler


More NGM issues.

More NGM issues.

--- src/clojure/kamituel/ngm_toc/data/ngm.cljc
+++ src/clojure/kamituel/ngm_toc/data/ngm.cljc
@@ -1462,4 +1462,49 @@
                          {:country "Kanada"}]}
                {:title "Hebrydy"
                 :description "Wystawione na wściekłe ataki północnego Atlantyku postrzępione szkockie wyspy kolonizowali tylko najtwardsi, ale i oni w końcu dali za wygraną, wiele z nich zostawiając morskim ptakom. Bezludne, wietrzne, surowe – od wieków zachwycają romantycznym pięknem."
-                :places [{:country "Wielka Brytania" :region "Szkocja" :coords [57.4 -6.3]}]}]}])
+                :places [{:country "Wielka Brytania" :region "Szkocja" :coords [57.4 -6.3]}]}]}
+   {:year 2011 :month 9 :vol 144
+    :articles [{:title "Wywiad"
+                :description "Wywiad z prof. Franciszkiem Adamickim m.in. o tym, jak bardzo zestresowane są pomidory, gdzie się podziały złote renety i dlaczego czarna marchew jest tak rzadka."}
+               {:title "Władcy Sahary"
+                :description "Tuaregowie przez wieki rządzili pustynią. Znajdowali drogę, kierując się kolorem, fakturą i smakiem piasku. Dziś karawany odchodzą w przeszłość, a z nimi tradycja tego ludu."
+                :places [{:country "Niger" :region "Sahara" :coords [18.6 7.1]}]}
+               {:title "Słonie sieroty"
+                :description "Choć ogromne i gruboskórne, słonie są bardzo wrażliwe. Potrafią się wspierać, pocieszać i przeżywać żałobę. "
+                :places [{:country "Kenia"}]}
+               {:title "Kto nam da skrzydła?"
+                :description "Odrzutowy silnik na plecach jak z kart komiksów? Czemu nie, w końcu swobodne latanie to odwieczne marzenie ludzkości. I wydaje się, że „osobisty pojazd latający” jest już coraz bliżej."}
+               {:title "Birma"
+                :description "Nazywana „klejnotem Azji” i „krajem tysiąca pagód” Birma zachowała nieskażone nowoczesnością pejzaż i kulturę. Dziś otwiera się po dziesięcioleciach politycznej i gospodarczej izolacji."
+                :places [{:country "Birma" :coords [21.7 95.9]}]}
+               {:title "Amundsen"
+                :description "Amundsen kontra Scott, psy kontra kuce. Wyścig do bieguna był starciem ambicji, charakterów, narodowych mentalności, a także specyficznie rozumianej „polarnej technologii”."
+                :places [{:region "Antarktyda" :coords [-78.8 -164.9]}]}
+               {:title "Myśląca sieć"
+                :description "Pierwszą na świecie elektrownię zbudował Thomas Edison w 1882 r. w Nowym Jorku. Choć odtąd ilość prądożernego sprzętu rośnie lawinowo, światowa sieć energetyczna oparta jest na technice rodem z I poł. XX w. I jeśli ma nas nie zawieść, musimy jej przydać inteligencji."}]}
+   {:year 2011 :month 8 :vol 143
+    :articles [{:title "Wywiad"
+                :description "Wywiad z paleontologiem Stephenem Brusatte m.in. o przyczynach niebywałego ewolucyjnego sukcesu dinozaurów."}
+               {:title "Kleopatra"
+                :description "Błyskotliwa i odważna piękność. Kochanka wodzów Rzymu, pierwsza celebrytka świata, a zarazem ostatnia władczyni na tronie faraonów. Wiemy o niej zdumiewająco mało, ale archeolodzy próbują tę wiedzę poszerzyć."
+                :places [{:country "Egipt"}]}
+               {:title "Park na szynach"
+                :description "Nowy Jork zamienił starą linię kolejową na zieloną promenadę. Parkowy wąż na stalowych podporach przeskakuje ulice metropolii."
+                :places [{:country "USA" :city "Nowy Jork" :coords [40.747814 -74.004872]}]}
+               {:title "Misie duchy"
+                :description "Niedźwiedzie Kermode są białe, choć rodziców często mają czarnych.
+W deszczowej puszczy przemykają jak duchy. I tak traktowali je Indianie."
+                :places [{:country "Kanada" :region "Kolumbia Brytyjska" :coords [52.9 -128.9]}]}
+               {:title "Androidy"
+                :description "Roboty łudząco podobne do człowieka to już rzeczywistość. Zapewne wkrótce znajdą się w naszym otoczeniu. Jak zmienią relacje między ludźmi? Jakie zadania będziemy skłonni im powierzyć? A przede wszystkim – jak odnieść do nich
+kwestie moralności?"}
+               {:title "Balsa"
+                :description "Rośnie szybko, ostro, ryzykownie i w ogóle nie przejmuje się wagą. A jej kwiaty produkują nocą beczkę nektaru, który przyciąga licznych dwu-, cztero- i więcej- nożnych amatorów."
+                :places [{:region "Ameryka Południowa"}
+                         {:region "Ameryka Środkowa"}]}
+               {:title "Pendżab"
+                :description "Najbogatsza i najludniejsza prowincja Pakistanu chce korzystać z uroków doczesności i pozostaje pod wpływem roztańczonego sufizmu. A to nie podoba się talibom."
+                :places [{:country "Pakistan" :region "Pendżab" :coords [31.3 73.0]}]}
+               {:title "Pustynia Namib"
+                :description "Parki narodowe na blisko połowie powierzchni kraju? Tak, Namibia ma wielkie ambicje. Ale diamenty i inne minerały też kuszą."
+                :places [{:country "Namibia" :region "Pustynia Namib" :coords [-24 15]}]}]}])