Major rework of the encoding code

Major rework of the encoding code

No calculate the ideal bitrate based on factors such as audio length,
channels and sampling rate for a production. If a suitable bitrate can
be found, do the encoding, otherwise defer to manual volume splitting.

--- src/mdr2/encode.clj
+++ src/mdr2/encode.clj
@@ -5,15 +5,40 @@
             [me.raynes.fs :as fs]
             [mdr2.production :as prod]
             [mdr2.production.path :as path]
+            [mdr2.dtb :as dtb]
             [mdr2.pipeline1 :as pipeline]))

+;; according to wikipedia it should be 737280000 (see
+;; http://en.wikipedia.org/wiki/CD-ROM#Capacity) but according to k3b
+;; it is 666.4 MiB (2,048 B * 341,186 blocks = 698,748,928 B)
+(def ^:private max-size
+  "Max number of bytes that fit on a CD-ROM"
+  698748928)
+
+(def sampling-rates {:mono 22050.0 :stereo 44100.0})
+
+(defn sampling-rate
+  "Return the sampling rate that should be used for the given
+  `production`. By default 22050.0 is used but for stereo productions
+  we use 44100.0"
+  [production]
+  (let [dtb (path/recorded-path production)
+        channels (dtb/audio-channels dtb)]
+    (if (= channels 1)
+      (:mono sampling-rates)
+      (:stereo sampling-rates))))
+
 (defn encode-production
-  "Encode a `production`, i.e. convert the wav files to mp3"
-  [production]
+  "Encode a `production` using the given `bitrate`, i.e. convert the
+  wav files to mp3"
+  [production bitrate]
   (let [output (path/encoded-path production)
-        manifest (path/manifest-path production)]
+        manifest (path/manifest-path production)
+        stereo (if (dtb/mono? (path/recorded-path production)) "mono" "stereo")
+        sampling-rate (sampling-rate production)]
     (fs/mkdir output)
-    (pipeline/audio-encoder {:input (.getPath manifest) :output (.getPath output)})))
+    (pipeline/audio-encoder (.getPath manifest) (.getPath output)
+                            :bitrate bitrate :stereo stereo :freq sampling-rate)))

 (defn create-iso
   "Pack a production in an iso file"
@@ -32,20 +57,26 @@
         "-J" ; Generate Joliet directory records in addition to regular ISO9660 filenames.
         "-o" iso-name encoded-path)))

-;; according to wikipedia it should be 737280000 (see
-;; http://en.wikipedia.org/wiki/CD-ROM#Capacity) but according to k3b
-;; it is 666.4 MiB (2,048 B * 341,186 blocks = 698,748,928 B)
-(def ^:private max-size
-  "Max number of bytes that fit on a CD-ROM"
-  698748928)
+(def bitrates
+  "Possible bitrates for encoding"
+  [128 64 48])

-(defn fit-on-one-cd?
-  "Return true if the `production`, i.e. the resulting iso file fits
-  on one CD"
+(defn ideal-bitrate
+  "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."
   [production]
-  (let [path (path/iso-path production)
-        size (fs/size path)]
-    (< size max-size)))
+  (let [dtb (path/recorded-path production)
+        duration (dtb/audio-length dtb)
+        sampling-ratio (if (dtb/mono? dtb) 1/2 1)
+        max-bitrate (/ (* (/ max-size duration sampling-ratio) 8) 1000)]
+    (loop [bitrates bitrates]
+      (when-first [bitrate bitrates]
+        (if (> max-bitrate bitrate)
+          bitrate
+          (recur (rest bitrates)))))))

 (defn clean-up
   "Clean up temporary files of a production, namely the mp3 encoded
@@ -56,15 +87,15 @@

 (defn encode
   [production]
-  ;; encode the production
-  (encode-production production)
-  ;; create an iso
-  (create-iso production)
-  (if (fit-on-one-cd? production)
-    ;; set the state to encoded
-    (prod/update! (assoc production :state :encoded))
+  (if-let [bitrate (ideal-bitrate production)]
+    (do
+      ;; encode the production
+      (encode-production production bitrate)
+      ;; downgrade to daisy202
+
+      ;; create an iso
+      (create-iso production)
+      ;; set the state to encoded
+      (prod/update! (assoc production :state :encoded)))
     ;; otherwise move the production to state :pending-volume-split
-    ;; FIXME: clean up first
-    (do
-      (clean-up production)
-      (prod/update! (assoc production :state :pending-volume-split)))))
+    (prod/update! (assoc production :state :pending-volume-split))))


Added close view of stained glass

Added close view of stained glass

--- src/game/main_game.cljs
+++ src/game/main_game.cljs
@@ -21,6 +21,27 @@
         (.. game -add (sprite 0 0 "world"))
         (set! (.. this -player) (.. game -add (sprite 280 540 "player")))
         (set! (.. this -weaponSprite) (.. game -add (sprite 295 5 "weapon")))
+
+        ;; Glasses
+
+        (let [gs (.. game -add (sprite 0 100 "glass1"))]
+          (set! (.. gs -visible) false)
+          (set! (.. gs -fixedToCamera) true)
+          (set! (.. this -g1) gs))
+        (let [gs (.. game -add (sprite 0 100 "glass2"))]
+          (set! (.. gs -visible) false)
+          (set! (.. gs -fixedToCamera) true)
+          (set! (.. this -g2) gs))
+        (let [gs (.. game -add (sprite 0 100 "glass3"))]
+          (set! (.. gs -visible) false)
+          (set! (.. gs -fixedToCamera) true)
+          (set! (.. this -g3) gs))
+        (let [gs (.. game -add (sprite 0 100 "glass4"))]
+          (set! (.. gs -visible) false)
+          (set! (.. gs -fixedToCamera) true)
+          (set! (.. this -g4) gs))
+
+

         ;; Define animations
         (.. this -player -animations (add "down" (clj->js [0 1 2]) anim-frame-rate true))
@@ -70,7 +91,7 @@
         (set! (.. this -throneRect) (js/Phaser.Rectangle. 225 20 170 195))
         (set! (.. this -throneEvents) (:throne dialogueTree))

-        (set! (.. this -doorRect) (js/Phaser.Rectangle. 280 540 40 40))
+        (set! (.. this -doorRect) (js/Phaser.Rectangle. 285 540 40 40))
         (set! (.. this -doorEvents) (:door dialogueTree))

         (set! (.. this -weapon) false)
@@ -103,9 +124,22 @@
               (.. game -state (start "ending")))
             ))

+        ;; hide all glasses until we know we're in a dialogue
+        (do
+          (set! (.. this -g1 -visible) false)
+          (set! (.. this -g2 -visible) false)
+          (set! (.. this -g3 -visible) false)
+          (set! (.. this -g4 -visible) false))
+
         ;; Dialogue situation - no movement
         (if-let [d (seq (.-dialogue this))]
           (do
+            (when-let [g (.. this -currentGlass)]
+              (case g
+                :glass1  (set! (.. this -g1 -visible) true)
+                :glass2 (set! (.. this -g2 -visible) true)
+                :glass3 (set! (.. this -g3 -visible) true)
+                :glass4 (set! (.. this -g4 -visible) true)))
             (.. this -dialogueText (setText (first d)))
             (when (and (.. this -spacebar -isDown)
                        (> (- (.. game -time -now)
@@ -115,8 +149,6 @@
                 (set! (.. this -lastSpace) (.. game -time -now))
                 (.. this -dialogueText (setText ""))
                 (set! (.-dialogue this) (rest d)))))
-
-

           ;; Basic Movement


Send JSON accept header for multi-lingual status pages. No idea how to test

--- src/greenyet/status.clj
+++ src/greenyet/status.clj
@@ -54,7 +54,7 @@

 (defn- fetch-status [url host-config]
   (try
-    (let [response (client/get url)]
+    (let [response (client/get url {:accept "application/json"})]
       (if (= 200 (:status response))
         (application-status response host-config)
         {:color :red


Re-implement core to gain performance and simplify code #44 - error reporting for misspelled old value ref

--- src/flatgui/base.clj
+++ src/flatgui/base.clj
@@ -30,7 +30,12 @@
 (def old-val-prefix "old-")

 (defn old-value-ref? [e property]
-  (and (not (nil? property)) (symbol? e) (.startsWith (name e) old-val-prefix) (.endsWith (name e) (name property))))
+  (and
+    (not (nil? property))
+    (symbol? e)
+    (.startsWith (name e) old-val-prefix)
+    (.endsWith (name e) (name property))
+    (= (.length (str e)) (+ (.length old-val-prefix) (dec (.length (str property)))))))

 (declare replace-gp)
 (declare replace-gpv)


Refactored compiler matching conditions

Refactored compiler matching conditions

--- src/hiccup/compiler.clj
+++ src/hiccup/compiler.clj
@@ -83,23 +83,10 @@
     (seq? data)    (apply str (map render-html data))
     :otherwise     (as-str data)))

-(defmacro match-pattern
-  "Match and destructure the supplied pattern."
-  [target pattern & body]
-  (let [binds (map #(if (seq? %) (last %) %) pattern)
-        preds (remove symbol? pattern)
-        target-sym (gensym target)
-        length-eq? (if-not (contains? (set pattern) '&)
-                    `((= (count ~target-sym) ~(count pattern))))]
-    `(let [~target-sym ~target, [~@binds] ~target-sym]
-       (when (and ~@length-eq? ~@preds)
-         ~@body))))
-
-(defmacro case-pattern
-  "A case statement that employs match-pattern."
-  [target & clauses]
-  `(or ~@(for [[pattern body] (partition 2 clauses)]
-           `(match-pattern ~target ~pattern ~body))))
+(defn- quoted?
+  "True if x is a quoted symbol."
+  [x]
+  (and (seq? x) (= (first x) `quote)))

 (defn- literal?
   "True if x is a literal value that can be rendered as-is."
@@ -108,7 +95,7 @@
        (or (not (vector? x))
            (every? literal? x))
        (or (not (seq? x))
-           (= (first x) `quote))))
+           (quoted? x))))

 (declare compile-html)

@@ -124,14 +111,14 @@

 (defn compile-tag
   "Pre-compile a single tag vector where possible."
-  [element]
-  (case-pattern element
-    [& (every? literal? content)]
+  [[tag attrs & content :as element]]
+  (cond
+    (every? literal? element)
       (render-tag (eval element))
-    [(literal? tag) (map? attrs) & content]
+    (and (literal? tag) (map? attrs))
       (compile-partial-tag tag attrs content)
-    [& content]
-      `(render-tag [~@(compile-html content)])))
+    :else
+      `(render-tag [~@(compile-html element)])))

 (defn compile-html
   "Pre-compile data structures into HTML where possible."


update request->auth-token to check for Token in the authorization header

--- src/gangway/auth.clj
+++ src/gangway/auth.clj
@@ -12,9 +12,10 @@
   (let [auth (get-in ctx [:request :headers "authorization"])]
     (if (nil? auth)
       (str "")
-      (second (split
-           (get-in ctx [:request :headers "authorization"])
-           #"\s+")))))
+      (let [split-auth (split auth #"\s+")]
+        (if (= (str "Token") (first split-auth))
+          (second split-auth)
+          (str ""))))))

 (defn gen-token
   "Generates a random token of a specified length consisting


Fixed bad doc-string for ->str

Fixed bad doc-string for ->str

--- src/labs/redis/core.clj
+++ src/labs/redis/core.clj
@@ -55,8 +55,9 @@
   (.getValue reply))

 (let [byte-array-class (Class/forName "[B")]
-  (defn ->str [reply]
+  (defn ->str
     "Coerces reply into a String."
+    [reply]
     (condp instance? reply
       byte-array-class (String. ^bytes reply)
       BulkReply (String. (.bytes ^BulkReply reply))


eliminate privacy

eliminate privacy

--- src/id3.clj
+++ src/id3.clj
@@ -7,24 +7,24 @@
 		[clojure.java.io :as io]
 		[org.clojars.smee.binary.core :as b]))

-(def ^:private default-padding 1024)
+(def default-padding 1024)

 (defn body-size [tag]
 	(apply + (map #(+ 10 (common/frame-body-size %)) (::frames tag))))

-(def ^:private id3-header (b/ordered-map
+(def id3-header (b/ordered-map
 	::magic-number (b/constant (b/string latin1 :length 3) "ID3")
 	::version (b/enum :byte {3 3 4 4})
 	::revision :byte
 	::flags (b/bits [nil nil nil nil :id3.flag/footer :id3.flag/experimental :id3.flag/extended-header :id3.flag/unsynchronized]) ; ID3v2.3 doesn't really have a footer tag, but it's not worth the complexity of separate header codecs
 	::size common/synchsafe-int))

-(def ^:private text-frame-keys #:id3.frame.type{
+(def text-frame-keys #:id3.frame.type{
 	:text [:id3.frame/content]
 	:user-text [:id3.frame/description :id3.frame/content]
 	:picture [:id3.frame/description]})

-(def ^:private id3
+(def id3
 	(b/header id3-header
 		(fn [header] (b/compile-codec (common/body-codec header)
 			#(apply dissoc % (keys header))
@@ -36,28 +36,28 @@
 			::flags (set/intersection flags #{:id3.flag/experimental})
 			::size (max size (body-size tag))})))

-(defn ^:private group-frames-by [k frames content-key]
+(defn group-frames-by [k frames content-key]
 	(into {}
 		(for [[desc [first & extra]] (group-by k frames)]
 			(if extra (error "Multiple %s:%s frames" (:id3.frame/id first) desc)
 				[desc (content-key first)]))))

-(defn ^:private cannot-encode? [encoder value]
+(defn cannot-encode? [encoder value]
 	(let [f #(not (.canEncode encoder %))]
 		(if (coll? value)
 			(some f value)
 			(f value))))

-(defn ^:private cannot-encode-latin1? [frame]
+(defn cannot-encode-latin1? [frame]
 	(let [latin1-encoder (.newEncoder (java.nio.charset.Charset/forName latin1))]
 		(some #(cannot-encode? latin1-encoder (% frame))
 			(text-frame-keys (common/frame-type (:id3.frame/id frame))))))

-(defn ^:private safe-encoding [tag]
+(defn safe-encoding [tag]
 	({3 utf16 4 utf8}
 		(::version tag)))

-(defn ^:private set-encoding [encoding tag]
+(defn set-encoding [encoding tag]
 	(update-in tag [::frames]
 		(partial map (fn [frame]
 			(cond
@@ -71,7 +71,7 @@
 				:else
 					frame)))))

-(defn ^:private full->normal [tag]
+(defn full->normal [tag]
 	(into {}
 		(for [[id [first-frame & extra-frames :as frames]] (group-by :id3.frame/id (::frames tag))]
 			[id (case (common/frame-type id)
@@ -82,7 +82,7 @@
 				:id3.frame.type/picture (map #(select-keys % [:id3.frame/picture-type :id3.frame/mime-type :id3.frame/bytes]) frames)
 				:id3/frame.type/blob (map :id3.frame/bytes frames))])))

-(defn ^:private normal->full [version tag] {
+(defn normal->full [version tag] {
 	::magic-number "ID3"
 	::version version
 	::revision 0
@@ -103,14 +103,14 @@
 					:id3.frame.type/blob (for [content contents]
 						{:id3.frame/id id :id3.frame/bytes content}))))))})

-(defn ^:private full->simple [tag]
+(defn full->simple [tag]
 	(let [id->name (set/map-invert (common/frame-names-for-version (::version tag)))]
 		(into {}
 			(for [[id contents] (full->normal tag)]
 				(when-let [key (id->name id)]
 					[key contents])))))

-(defn ^:private simple->full [version tag]
+(defn simple->full [version tag]
 	(let [name->id (common/frame-names-for-version version)]
 		(normal->full version
 			(into {} (for [[key contents] tag]
@@ -118,7 +118,7 @@
 					[id contents]
 					(error "Unknown frame key (%s)" key)))))))

-(defn ^:private read-header [path]
+(defn read-header [path]
 	(with-open [f (io/input-stream path)]
 		(b/decode id3-header f)))

@@ -147,7 +147,7 @@
 			:simple full->simple)]
 		(downconvert tag)))

-(defn ^:private add-padding [padding tag]
+(defn add-padding [padding tag]
 	(assoc tag ::size
 		(+ (body-size tag)
 			(or padding default-padding))))


figwheel.main: default options for node target

--- figwheel-main/src/figwheel/main.cljc
+++ figwheel-main/src/figwheel/main.cljc
@@ -441,7 +441,8 @@
                            nil))
                     "target")]
           (fw-util/dir-on-classpath? target-dir))
-        temp-dir (when-not target-on-classpath?
+        temp-dir (when-not (or (= :nodejs (:target (:options cfg)))
+                               target-on-classpath?)
                    (let [tempf (java.io.File/createTempFile "figwheel" "repl")]
                      (.delete tempf)
                      (.mkdirs tempf)
@@ -452,8 +453,12 @@
      repl-env-fn
      (-> cfg
          (cond->
-             temp-dir (assoc-in [:options :output-dir] (default-output-dir temp-dir))
-             temp-dir (assoc-in [:options :output-to]  (default-output-to temp-dir))
+             temp-dir (assoc-in [:options :output-dir]
+                                (default-output-dir
+                                 (assoc cfg [::config :target-dir] temp-dir)))
+             temp-dir (assoc-in [:options :output-to]
+                                (default-output-to
+                                 (assoc cfg [::config :target-dir] temp-dir)))
              temp-dir (assoc-in [:options :asset-path]  "cljs-out"))
          (assoc :args args)
          (update :options (fn [opt] (merge {:main 'figwheel.repl.preload} opt)))
@@ -560,16 +565,42 @@
 ;; Config
 ;; ----------------------------------------------------------------------------

-(defn default-output-dir [target & [scope]]
+(defn default-output-dir* [target & [scope]]
   (->> (cond-> [(or target "target") "public" "cljs-out"]
          scope (conj scope))
        (apply io/file)
        (.getPath)))

-(defn default-output-to [target & [scope]]
+(defmulti default-output-dir (fn [{:keys [options]}]
+                               (get options :target :browser)))
+
+(defmethod default-output-dir :default [{:keys [::config ::build]}]
+  (default-output-dir* (:target-dir config) (:id build)))
+
+(defmethod default-output-dir :nodejs [{:keys [::config ::build]}]
+  (let [target (:target-dir config "target")
+        scope (:id build)]
+    (->> (cond-> [target "node"]
+           scope (conj scope))
+         (apply io/file)
+         (.getPath))))
+
+(defn default-output-to* [target & [scope]]
   (.getPath (io/file (or target "target") "public" "cljs-out"
                      (cond->> "main.js"
                        scope (str scope "-")))))
+
+(defmulti default-output-to (fn [{:keys [options]}]
+                              (get options :target :browser)))
+
+(defmethod default-output-to :default [{:keys [::config ::build]}]
+  (default-output-to* (:target-dir config) (:id build)))
+
+(defmethod default-output-to :nodejs [{:keys [::build] :as cfg}]
+  (let [scope (:id build)]
+    (.getPath (io/file (default-output-dir cfg)
+                       (cond->> "main.js"
+                         scope (str scope "-"))))))

 (defn extra-config-merge [a' b']
   (merge-with (fn [a b]
@@ -706,32 +737,29 @@
 (defn- config-default-dirs [{:keys [options ::config ::build] :as cfg}]
   (cond-> cfg
     (nil? (:output-to options))
-    (assoc-in [:options :output-to] (default-output-to
-                                     (:target-dir config)
-                                     (:id build)))
+    (assoc-in [:options :output-to] (default-output-to cfg))
     (nil? (:output-dir options))
-    (assoc-in [:options :output-dir] (default-output-dir
-                                      (:target-dir config)
-                                      (:id build)))))
+    (assoc-in [:options :output-dir] (default-output-dir cfg))))

 (defn figure-default-asset-path [{:keys [figwheel-options options ::config ::build] :as cfg}]
-  (let [{:keys [output-dir]} options]
-    ;; TODO could discover the resource root if there is only one
-    ;; or if ONLY static file serving can probably do something with that
-    ;; as well
-    ;; UNTIL THEN if you have configured your static resources no default asset-path
-    (when-not (contains? (:ring-stack-options figwheel-options) :static)
-      (let [parts (fw-util/relativized-path-parts (or output-dir
-                                                      (default-output-dir
-                                                       (:target-dir config)
-                                                       (:id build))))]
-        (when-let [asset-path
-                   (->> parts
-                        (split-with (complement #{"public"}))
-                        last
-                        rest
-                        not-empty)]
-          (str (apply io/file asset-path)))))))
+
+  (if (= :nodejs (:target options))
+    (:output-dir options)
+    (let [{:keys [output-dir]} options]
+      ;; TODO could discover the resource root if there is only one
+      ;; or if ONLY static file serving can probably do something with that
+      ;; as well
+      ;; UNTIL THEN if you have configured your static resources no default asset-path
+      (when-not (contains? (:ring-stack-options figwheel-options) :static)
+        (let [parts (fw-util/relativized-path-parts (or output-dir
+                                                        (default-output-dir cfg)))]
+          (when-let [asset-path
+                     (->> parts
+                          (split-with (complement #{"public"}))
+                          last
+                          rest
+                          not-empty)]
+            (str (apply io/file asset-path))))))))

 ;; targets options
 (defn- config-default-asset-path [{:keys [options] :as cfg}]
@@ -1102,7 +1130,8 @@
                            nil))
                     "target")]
           (fw-util/dir-on-classpath? target-dir))
-        temp-dir (when-not target-on-classpath?
+        temp-dir (when-not (or (= :nodejs (:target (:options cfg)))
+                               target-on-classpath?)
                    (let [tempf (java.io.File/createTempFile "figwheel" "repl")]
                      (.delete tempf)
                      (.mkdirs tempf)
@@ -1111,8 +1140,10 @@
                      tempf))
         cfg (-> cfg
                 (cond->
-                    temp-dir (assoc-in [:options :output-dir] (default-output-dir temp-dir))
-                    temp-dir (assoc-in [:options :output-to]  (default-output-to temp-dir))
+                    temp-dir (assoc-in [:options :output-dir]
+                                       (default-output-dir* temp-dir))
+                    temp-dir (assoc-in [:options :output-to]
+                                       (default-output-to* temp-dir))
                     temp-dir (assoc-in [:options :asset-path]  "cljs-out"))
                 (assoc-in [:options :aot-cache] false)
                 (update :options #(assoc % :main


CMR-1876: Add common-app-lib as dependency for umm-lib

--- umm-lib/project.clj
+++ umm-lib/project.clj
@@ -5,6 +5,7 @@
   :url "***REMOVED***projects/CMR/repos/cmr/browse/umm-lib"

   :dependencies [[org.clojure/clojure "1.7.0"]
+                 [nasa-cmr/cmr-common-app-lib "0.1.0-SNAPSHOT"]
                  [nasa-cmr/cmr-common-lib "0.1.1-SNAPSHOT"]
                  [nasa-cmr/cmr-spatial-lib "0.1.0-SNAPSHOT"]]


React needs indexes on multiple cells

React needs indexes on multiple cells

--- src/livewator/core.cljs
+++ src/livewator/core.cljs
@@ -60,18 +60,21 @@
 ; Plots the playfield, it is a table of size w*h
 ;

-(defmulti plot-cell (fn [data] (:tipo data)))
+(defmulti plot-cell (fn [data _] (:tipo data)))

 (defmethod plot-cell :PESCE
-  [data]
+  [data idx]
+  ^{:key idx}
   [:td {:class (name (:colore data))}  (str "P" (:energia data)) ] )

 (defmethod plot-cell :SQUALO
-  [data]
-  [:td {:class (name (:colore data))}  (str "x<" (:energia data)) ] )
+  [data idx]
+   ^{:key idx}
+   [:td {:class (name (:colore data))}  (str "<" (:energia data)) ] )

 (defmethod plot-cell nil
-  [data]
+  [data idx]
+  ^{:key idx}
   [:td ""] )

@@ -86,8 +89,9 @@
   [nrow rowdata]

   ^{:key (str "r-" nrow)} [:tr
-    [:td (str nrow)]
-    (map plot-cell rowdata)
+    ^{:key "0"} [:td  (str nrow)]
+    ;(map plot-cell rowdata)
+    (map-indexed (fn [idx itm] (plot-cell itm (str idx))) rowdata)
     ]
   )

@@ -101,8 +105,8 @@
    {:cell-spacing "0"}

    [:thead>tr
-    [:td {:width "20px"} "-"]
-    (map #(vec [:th {:width "20px"} (str %)]) (range m/PLAYFIELD-WIDTH))]
+    [:th {:width "20px"} "-"]
+    (map #(vec  [:th {:key (str %) :width "20px"} (str %)]) (range m/PLAYFIELD-WIDTH))]

    [:tbody


Add remove-gutter to editor

Add remove-gutter to editor

--- src/lt/objs/editor.cljs
+++ src/lt/objs/editor.cljs
@@ -384,6 +384,20 @@
                    (set-options e {:gutters (clj->js gutter-classes)})
                    (doseq [[k v] new-gutter-widths]
                      (dom/set-css (dom/$ (str "div." k) gutter-div) {"width" (str v "px")}))))))
+
+(defn remove-gutter [e class-name]
+  (let [gutter-classes (remove #{class-name} (js->clj (option e "gutters")))
+        gutter-div (dom/$ :div.CodeMirror-gutters (object/->content e))
+        gutter-divs (dom/$$ :div.CodeMirror-gutter gutter-div)
+        current-widths (reduce (fn [res gutter]
+                                 (let [gutter-class (clojure.string/replace-first (dom/attr gutter "class") "CodeMirror-gutter " "")]
+                                   (assoc res gutter-class (dom/width gutter)))
+                                 ) {} gutter-divs)]
+    (operation e (fn[]
+                   (set-options e {:gutters (clj->js gutter-classes)})
+                   (doseq [[k v] new-gutter-widths]
+                     (if-let [gutter (dom/$ (str "div." k) gutter-div)]
+                       (dom/set-css gutter {"width" (str v "px")})))))))

 ;;*********************************************************
 ;; Object


Another manual ns form fix

Another manual ns form fix

--- src/metabase/driver.clj
+++ src/metabase/driver.clj
@@ -4,6 +4,7 @@
             [medley.core :as m]
             [metabase.models
              [database :refer [Database]]
+             field
              [setting :refer [defsetting]]]
             [metabase.util :as u]
             [toucan.db :as db])


Add docstrs for public vars missing them in metabase.driver :yum:

--- src/metabase/driver.clj
+++ src/metabase/driver.clj
@@ -13,7 +13,7 @@
             [metabase.util :as u])
   (:import clojure.lang.Keyword))

-(declare -dataset-query query-fail query-complete save-query-execution)
+(declare query-fail query-complete save-query-execution)

 ;;; ## INTERFACE + CONSTANTS

@@ -203,14 +203,16 @@
                                   more)))))

 (defn default-field-percent-urls
-  "Default implementation for optional driver fn `:field-percent-urls` that calculates percentage in Clojure-land."
+  "Default implementation for optional driver fn `field-percent-urls` that calculates percentage in Clojure-land."
   [driver field]
   (->> (field-values-lazy-seq driver field)
        (filter identity)
        (take max-sync-lazy-seq-results)
        percent-valid-urls))

-(defn default-field-avg-length [driver field]
+(defn default-field-avg-length
+  "Default implementation of optional driver fn `field-avg-length` that calculates the average length in Clojure-land via `field-values-lazy-seq`."
+  [driver field]
   (let [field-values        (->> (field-values-lazy-seq driver field)
                                  (filter identity)
                                  (take max-sync-lazy-seq-results))
@@ -462,6 +464,7 @@
       (merge query-result)))

 (defn save-query-execution
+  "Save (or update) a `QueryExecution`."
   [{:keys [id] :as query-execution}]
   (if id
     ;; execution has already been saved, so update it
@@ -470,3 +473,6 @@
       query-execution)
     ;; first time saving execution, so insert it
     (m/mapply ins QueryExecution query-execution)))
+
+
+(u/require-dox-in-this-namespace)


Clean up requirements and imports.

Clean up requirements and imports.

--- src/multihash/core.cljc
+++ src/multihash/core.cljc
@@ -3,13 +3,10 @@
   (:require
     [alphabase.base58 :as b58]
     [alphabase.bytes :as bytes]
-    [alphabase.hex :as hex]
-    [clojure.string :as str])
+    [alphabase.hex :as hex])
   #?(:clj (:import
             (clojure.lang ILookup IMeta IObj)
-            java.io.InputStream
-            java.nio.ByteBuffer
-            java.security.MessageDigest)))
+            java.io.InputStream)))

 ;; ## Hash Function Algorithms


fix log ability log message sent even when can't be played

--- src/node/game/core.cljs
+++ src/node/game/core.cljs
@@ -26,14 +26,15 @@
 (defn do! [{:keys [cost effect]}]
   (fn [state side args]
     (if cost
-     (when (apply pay (concat [state side] cost))
-       (effect state side args))
+     (if (apply pay (concat [state side] cost))
+       (effect state side args)
+       false)
      (effect state side args))))

 (defn create-deck [deck]
   (shuffle (mapcat #(repeat (:qty %) (:card %)) (:cards deck))))

-(defn init-game [{:keys [players gameid log] :as game}]
+(defn init-game [{:keys [players gameid] :as game}]
   (let [corp (some #(when (= (:side %) "Corp") %) players)
         runner (some #(when (= (:side %) "Runner") %) players)
         corp-deck (create-deck (:deck corp))
@@ -124,8 +125,8 @@

 (defn play-ability [state side {:keys [card ability]}]
   (let [ab (get-in game.cards/cards [(:title card) :abilities ability])]
-    ((do! ab) state side nil)
-    (system-msg state side (str "uses " (:title card) " to " (:msg ab) "."))))
+    (when ((do! ab) state side nil)
+      (system-msg state side (str "uses " (:title card) " to " (:msg ab) ".")))))

 (defn play-instant [state side card]
   (when (pay state side :click 1 :credit (:cost card) (when (has? card :subtype "Double") [:click 1]))


commen added

commen added

--- src/notehub/storage.clj
+++ src/notehub/storage.clj
@@ -36,6 +36,8 @@
       (redis :hset :publisher-key pid psk)
       psk)))

+; This was uncommented, because the DB isn't
+; available on heroku at compile time
 #_ (when-not (valid-publisher? "NoteHub")
   (register-publisher "NoteHub"))


Remove extensions that we don't need anymore.

--- src/onyx/extensions.clj
+++ src/onyx/extensions.clj
@@ -2,92 +2,15 @@
   "Extension interfaces for internally used queues, logs,
    and distributed coordination.")

-(defmulti mark-peer-born (fn [sync node] (type sync)))
+(defmulti write-log-entry (fn [log data] (type log)))

-(defmulti mark-peer-dead (fn [sync node] (type sync)))
+(defmulti read-log-entry (fn [log position] (type log)))

-(defmulti mark-offered (fn [sync task peer nodes] (type sync)))
+(defmulti register-pulse (fn [log id] (type log)))

-(defmulti plan-job (fn [sync job-id tasks catalog workflow] (type sync)))
+(defmulti on-delete (fn [log node ch] (type log)))

-(defmulti ack (fn [sync node] (type sync)))
-
-(defmulti seal-resource? (fn [sync node] (type sync)))
-
-(defmulti revoke-offer (fn [sync ack-node] (type sync)))
-
-(defmulti complete (fn [sync complete-node cooldown-node cb] (type sync)))
-
-(defmulti next-tasks (fn [sync] (type sync)))
-
-(defmulti idle-peers (fn [sync] (type sync)))
-
-(defmulti create
-  (fn
-    ([sync bucket] [(type sync) bucket])
-    ([sync bucket content] [(type sync) bucket])))
-
-(defmulti create-at
-  (fn
-    ([sync bucket subpath] [(type sync) bucket])
-    ([sync bucket subpath content] [(type sync) bucket])))
-
-(defmulti create-node
-  (fn
-    ([sync node] (type sync))
-    ([sync node contents] (type sync))))
-
-(defmulti delete (fn [sync node] (type sync)))
-
-(defmulti write-node (fn [sync node contents] (type sync)))
-
-(defmulti touch-node (fn [sync node] (type sync)))
-
-(defmulti touched? (fn [sync bucket node] [(type sync) bucket]))
-
-(defmulti read-node (fn [sync node] (type sync)))
-
-(defmulti read-node-at (fn [sync node & subpaths] [(type sync) node]))
-
-(defmulti list-nodes (fn [sync bucket] [(type sync) bucket]))
-
-(defmulti dereference (fn [sync node] (type sync)))
-
-(defmulti previous-node (fn [sync node] (type sync)))
-
-(defmulti smallest? (fn [sync bucket node] [(type sync) bucket]))
-
-(defmulti leader (fn [sync bucket] [(type sync) bucket]))
-
-(defmulti resolve-node (fn [sync bucket & subpath] [(type sync) bucket]))
-
-(defmulti children (fn [sync node] (type sync)))
-
-(defmulti node-exists? (fn [sync node] (type sync)))
-
-(defmulti node-exists-at? (fn [sync bucket & subpaths] [(type sync) bucket]))
-
-(defmulti creation-time (fn [sync node] (type sync)))
-
-(defmulti bucket (fn [sync bucket] [(type sync) bucket]))
-
-(defmulti bucket-at (fn [sync bucket subpath] [(type sync) bucket]))
-
-(defmulti version (fn [sync node] (type sync)))
-
-(defmulti on-change (fn [sync node cb] (type sync)))
-
-(defmulti on-child-change (fn [sync node cb] (type sync)))
-
-(defmulti on-delete (fn [sync node db] (type sync)))
-
-(defmulti next-offset (fn [sync bucket] [(type sync) bucket]))
-
-(defmulti speculate-offset (fn [sync offset] (type sync)))
-
-(defmulti log-entry-at (fn [sync bucket offset] [(type sync) bucket]))
-
-(defmulti checkpoint (fn [sync bucket offset] [(type sync) bucket]))
+(defmulti subscribe-to-log (fn [log starting-position ch] (type log)))

 (defmulti create-tx-session (fn [queue] (type queue)))

@@ -132,22 +55,3 @@
   (fn [element parents children]
     (:onyx/type element)))

-;;;;;;;;;;;; New ZooKeeper API ;;;;;;;;;;;;;;;;;
-
-(defmulti write-log-entry
-  (fn [log data] (type log)))
-
-(defmulti read-log-entry
-  (fn [log position] (type log)))
-
-(defmulti register-pulse
-  (fn [log id] (type log)))
-
-(defmulti on-delete
-  (fn [log node ch] (type log)))
-
-(defmulti subscribe-to-log
-  (fn [log starting-position ch] (type log)))
-
-;;;;;;;;;;;; New ZooKeeper API ;;;;;;;;;;;;;;;;;
-


Defined the first and second inversion, ignoring extra tones for now.

--- src/overtunes/pitch.clj
+++ src/overtunes/pitch.clj
@@ -13,6 +13,15 @@
            (fn [name value] `(def ~name ~value))
            names
            (eval values))))
+
+(defn update-values
+  "Apply f to all the values of m corresponding to keys in ks."
+  [m [& ks] f] (if ks
+                 (update-values
+                   (update-in m [(first ks)] f)
+                   (rest ks)
+                   f)
+                 m))

 ; Basic intervals
 (def semitone 1)
@@ -65,3 +74,5 @@
 (def ninth #(assoc (seventh %) :ix (raise (:ii major-scale))))
 (def eleventh #(assoc (ninth %) :xi (raise (:iv major-scale))))
 (def thirteenth #(assoc (eleventh %) :xi (raise (:vi major-scale))))
+(def second-inversion #(update-values % [:iii :v] lower))
+(def first-inversion #(update-values % [:v] lower))


added MRC blog

added MRC blog


start removing unimplemented fn hints that we don't need. Also add mag and unhex.

--- src/processing/core.clj
+++ src/processing/core.clj
@@ -802,8 +802,6 @@
   [freeze-ms]
   (.delay *applet* (int freeze-ms)))

-;; $$die
-
 (defn directional-light
   "Adds a directional light. Directional light comes from one
   direction and is stronger when hitting a surface squarely and weaker
@@ -901,8 +899,6 @@
        (throw (Exception. (str "Unknown mode value: " mode ". Expected :close"))))
      (.endShape *applet* CLOSE)))

-;; $$exec
-
 (defn exit
   "Quits/stops/exits the program.  Rather than terminating
   immediately, exit will cause the sketch to exit after draw has
@@ -916,8 +912,6 @@
   value parameter."
   [val]
   (PApplet/exp (float val)))
-
-;; $$expand

 (defn fill-float
   "Sets the color used to fill shapes. For example, (fill 204 102 0),
@@ -985,9 +979,6 @@
      (let [mode (resolve-filter-mode mode)]
        (.filter *applet* (int mode) (float level)))))

-;; $$focusGained
-;; $$focusLost
-
 (defn focused
   "Returns a boolean value representing whether the applet has focus."
   []
@@ -1036,6 +1027,11 @@
   geeky debugging sessions much happier. "
   ([val] (PApplet/hex val))
   ([val num-digits] (PApplet/hex (int val) (int num-digits))))
+
+(defn unhex
+  "Converts a String representation of a hexadecimal number to its
+  equivalent integer value."
+  [hex-str] (PApplet/unhex (str hex-str)))

 (defn height
   "Height of the display window. The value of height is zero until
@@ -1150,9 +1146,6 @@
 ;; $$init
 ;; $$insertFrame
 ;; $$join
-;; $$keyPressed
-;; $$keyReleased
-;; $$keyTyped
 ;; $$lerp
 ;; $$lerpColor
 ;; $$lightFallof
@@ -1182,8 +1175,6 @@
      (.line *applet* (float x1) (float y1) (float z1)
             (float x2) (float y2) (float z2))))

-;; $$link
-
 (defn load-bytes [filename] (PApplet/loadBytes filename))

 (defn load-font [filename] (.loadFont *applet* filename))
@@ -1212,8 +1203,14 @@

 (defn start-loop [] (.loop *applet*))

-;; $$mag
-;; $$main
+(defn mag
+  "Calculates the magnitude (or length) of a vector. A vector is a
+  direction in space commonly used in computer graphics and linear
+  algebra. Because it has no start position, the magnitude of a vector
+  can be thought of as the distance from coordinate (0,0) to its (x,y)
+  value. Therefore, mag is a shortcut for writing (dist 0 0 x y)."
+  ([a b] (PApplet/mag (float a) (float b)))
+  ([a b c] (PApplet/mag (float a) (float b) (float c))))

 (defn map-to [val istart istop ostart ostop]
   (PApplet/map (float val) (float istart) (float istop) (float ostart) (float ostop)))
@@ -1225,9 +1222,6 @@
   ([^ints alpha-array] (.mask *applet* alpha-array)))

 (defn mask-image [^PImage img] (.mask *applet* img))
-
-;; $$match
-;; $$max

 (defn millis
   "Returns the number of milliseconds (thousandths of a second) since
@@ -1236,8 +1230,6 @@
   []
   (.millis *applet*))

-;; $$min
-
 (defn minute
   "Returns the current minute as a value from 0 - 59"
   []
@@ -1251,11 +1243,6 @@
   "Returns the current month as a value from 1 - 12."
   []
   (PApplet/month))
-
-;; $$nf
-;; $$nfc
-;; $$nfp
-;; $$nfs

 (defn mouse-x
   "Current horizontal coordinate of the mouse."
@@ -1345,14 +1332,6 @@
   ([] (.ortho *applet*))
   ([l r b t near far] (.ortho *applet* (float l) (float r) (float b)
                               (float t) (float near) (float far))))
-
-;; $$paint
-;; $$param
-;; $$parseBoolean
-;; $$parseByte
-;; $$parseChar
-;; $$parseFloat
-;; $$parseInt

 (defn perspective
   ([] (.perspective *applet*))
@@ -1481,15 +1460,6 @@
 (defn red [what] (.red *applet* (int what)))

 (defn redraw [] (.redraw *applet*))
-
-;; $$registerDispose
-;; $$registerDraw
-;; $$reqisterKeyEvent
-;; $$registerMouseEvent
-;; $$registerPost
-;; $$registerPre
-;; $$registerSize
-;; $$registerSize

 (defn request-image
   ([filename] (.requestImage *applet* filename))
@@ -1565,8 +1535,6 @@
   (.rotateZ *applet* (float angle)))

 (defn round [what] (PApplet/round (float what)))
-
-;; $$run

 (defn saturation [what] (.saturation *applet* (int what)))

@@ -1648,14 +1616,7 @@
 (defn set-image-at
   [dx dy ^PImage src] (.set *applet* (int dx) (int dy) src))

-;; $$setup
-
-;; $$setupExternalMessages
-;; $$setupFrameListener
-
 (defn shininess [shine] (.shininess *applet* (float shine)))
-
-;; $$shorten

 (defn sin
   "Calculates the sine of an angle. This function expects the values
@@ -1681,8 +1642,6 @@
   Note that smooth will also improve image quality of resized images."
   []
   (.smooth *applet*))
-
-;; $$sort

 (defn specular
   ([gray] (.specular *applet* (float gray)))
@@ -1710,10 +1669,6 @@
   ([res] (.sphereDetail *applet* (int res)))
   ([ures vres] (.sphereDetail *applet* (int ures) (int vres))))

-;; $$splice
-;; $$split
-;; $$splitTokens
-
 (defn spotlight
   ([r g b x y z nx ny nz angle concentration]
      (.spotLight *applet* r g b x y z nx ny nz angle concentration))
@@ -1735,11 +1690,6 @@
   [a]
   (PApplet/sqrt (float a)))

-;; $$start
-;; $$status
-;; $$stop
-;; $$str
-
 (def ^{:private true}
   stroke-cap-map {:square SQUARE
                   :round ROUND
@@ -1783,8 +1733,6 @@
   around shapes. All widths are set in units of pixels. "
   [weight]
   (.strokeWeight *applet* (float weight)))
-
-;; $$subset

 (defn tan [angle] (PApplet/tan (float angle)))

@@ -1876,18 +1824,6 @@
              (float x2) (float y2)
              (float x3) (float y3)))

-;; $$trim
-;; $$unhex
-;; $$unint
-;; $$unregisterDispose
-;; $$unregisterDraw
-;; $$unregiserKeyEvent
-;; $$unregiserMouseEvent
-;; $$unregiserKeyEvent
-;; $$unregiserPost
-;; $$unregisterPre
-;; $$unregisterSize
-;; $$update

 (defn update-pixels
   "Updates the display window with the data in the pixels array. Use
@@ -1985,8 +1921,7 @@
    corresponds to the official Processing.org version with which
    processing.core is compatible.")

-(defn
-  processing-version
+(defn processing-version
   "Returns clj-processing version as a printable string."
   []
   (str (:major *processing-version*)


Implement moving to edit state upon double click

--- src/reabledit/core.cljs
+++ src/reabledit/core.cljs
@@ -1,6 +1,7 @@
 (ns reabledit.core
   (:require [reabledit.components :as components]
             [reabledit.keyboard :as keyboard]
+            [reabledit.util :as util]
             [reagent.core :as reagent]))

 ;;
@@ -30,7 +31,8 @@
                                                 data
                                                 state
                                                 row-change-fn
-                                                element-id)}
+                                                element-id)
+        :on-double-click #(util/enable-edit! columns data state)}
        [:table
         [components/data-table-headers columns]
         [:tbody


format-message now accepts one or multiple events

--- src/riemann/hipchat.clj
+++ src/riemann/hipchat.clj
@@ -1,6 +1,7 @@
 (ns ^{:doc    "Forwards events to HipChat"
       :author "Hubert Iwaniuk"}
   riemann.hipchat
+  (:use [clojure.string :only [join]])
   (:require [clj-http.client :as client]
             [cheshire.core :as json]))

@@ -26,18 +27,24 @@
 (def ^:private chat-url
   "https://api.hipchat.com/v1/rooms/message?format=json")

-(defn- format-message [{:keys [host service state metric]}]
-  (str "Host: " host
-       ",\nservice: " service
-       ",\nstate: " state
-       ",\nmetric: " metric))
+(defn- format-message [ev]
+  "Formats a message, accepts a single
+  event or a sequence of events."
+  (join "\n\n"
+        (map
+          (fn [e]
+            (str
+              "Host: " (:host e)
+              " \nService: " (:service e)
+              " \nState: " (:state e)
+              " \nMetric: " (:metric e))) ev)))

 (defn- format-event [{:keys [room_id from notify message] :as conf} event]
   "Creates an event suitable for posting to hipchat."
   (merge {:color (set-message-colour event)}
          conf
          (when-not message
-           {:message (format-message event)})))
+           {:message (format-message (flatten [event]))})))

 (defn- post
   "POST to the HipChat API."


Add layer neuron count input.

Add layer neuron count input.

--- frontend/src/cljs/frontend/core.cljs
+++ frontend/src/cljs/frontend/core.cljs
@@ -33,11 +33,12 @@
 ;; -------------------------
 ;; View

-(defn atom-input [value]
-  [:input {:type "text"
-           :value @value
-           :on-change #(let [v (-> % .-target .-value)]
-                         (reset! value v))}])
+(defn atom-input [v k type]
+  [:input {:type (if type type "text")
+           :value (if k (k @v) @v)
+           :on-change #(let [text (-> % .-target .-value)]
+                         (if k (swap! v assoc k text)
+                             (reset! v text)))}])

 (defn selection-list [v k items]
   [:select.form-control {:field :list :id :many-options
@@ -46,10 +47,11 @@
      [:option {:key (:key item)}
       (:label item)])])

-(defn neuron-config [layer]
+(defn neuron-config [layer]
   [:div
    [selection-list layer :neuron-type neuron-types]
-   [selection-list layer :connectivity-type connectivity-types]])
+   [selection-list layer :connectivity-type connectivity-types]
+   [atom-input layer :neuron-count "number"]])

 (defn create-layer []
   (put! :layers (conj (get-state :layers)


Little bit of pca test code cleanup

Little bit of pca test code cleanup

--- test/pca_test.clj
+++ test/pca_test.clj
@@ -24,9 +24,7 @@
       (testing "from scratch"
                (is (almost-equal? (pc-from-start [1 1 1]) expected)))
       (testing "from scratch"
-               (is (almost-equal? (pc-from-start [1 1]) expected)))))
-
-         )
+               (is (almost-equal? (pc-from-start [1 1]) expected))))))

 (deftest wrapped-pca-test
@@ -45,11 +43,11 @@

   (testing "when initital start value is a zero eigenvector"
     (let [data (m/matrix [[1 -1  1 -1]
-                          [0 0 -1  1]
-                          [1 1 -1  0]])]
+                          [0  0 -1  1]
+                          [1  1 -1  0]])]
       (testing "should try another eigenvector"
         (is (not (almost-equal?
                    (wrapped-pca data 2)
-                   [0 0 0 0]))))))
+                   [0 0 0 0])))))))


Cleaned up the json body wrapping.

Cleaned up the json body wrapping.

--- src/shale/resources.clj
+++ src/shale/resources.clj
@@ -15,6 +15,10 @@
             [k v]))]
     (clojure.walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))

+(defn jsonify [m]
+  (json/generate-string
+    (json-keys m)))
+
 (defn build-session-url [request id]
   (URL. (format "%s://%s:%s%s/%s"
                 (name (:scheme request))
@@ -30,8 +34,7 @@
   :allowed-methods  [:get :post]
   :available-media-types  ["application/json"]
   :handle-ok (fn [context]
-               (json/generate-string
-                 (json-keys (shale.sessions/view-models nil))))
+               (jsonify (shale.sessions/view-models nil)))
   :post! (fn [context] )
   :post-redirect true
   :location #(build-session-url (get % :request) (get % ::id)))
@@ -40,8 +43,7 @@
   :allowed-methods [:get :put :delete]
   :available-media-types ["application/json"]
   :handle-ok (fn [context]
-               (json/generate-string
-                 (json-keys (::session context))))
+               (jsonify (::session context)))
   :delete! (fn [context]
              (shale.sessions/destroy-session id))
   :exists? (fn [context]


Whitespace

Whitespace

--- src/sojoban/levels.cljs
+++ src/sojoban/levels.cljs
@@ -19,4 +19,3 @@
 (defn ascii-level-to-board [ascii]
   (vov-map ascii-to-objset
            (string/split ascii #"\n\s*")))
-


Fix typo

Fix typo

--- server/src/patavi/server/handlers.clj
+++ server/src/patavi/server/handlers.clj
@@ -32,7 +32,7 @@
   (if (service/available? method)
     (dispatch-rpc method data)
     {:error {:uri service-rpc-uri
-             :message (str "service " method " not avaiable")}}))
+             :message (str "service " method " not available")}}))

 (def origin-re (re-pattern (:ws-origin-re config)))


Stop showing workflow-run UUID in UI

Stop showing workflow-run UUID in UI

--- src-cljs/frontend/components/pages/workflow.cljs
+++ src-cljs/frontend/components/pages/workflow.cljs
@@ -63,7 +63,7 @@
               [:div.build-info-header
                [:div.contextual-identifier
                 [:a {:href (routes/v1-run {:run-id id})}
-                 [:span (str run-name " " id)]]]]
+                 [:span run-name]]]]
               [:div.recent-commit-msg
                [:span.recent-log
                 {:title (when commit-body


Improve mention suggestions list

Improve mention suggestions list

Signed-off-by: Brian Sztamfater <760e7dab2836853c63805033e514668301fa9c47@status.im>

--- src/status_im/subs.cljs
+++ src/status_im/subs.cljs
@@ -1425,20 +1425,26 @@
  :<- [:chats/mentionable-contacts]
  :<- [:contacts/blocked-set]
  :<- [:multiaccount]
- (fn [[{:keys [chat-id users chat-type]} contacts blocked {:keys [name preferred-name public-key]}]]
-   (let [contacts-with-one-to-one (if (= chat-type constants/one-to-one-chat-type)
-                                    (assoc contacts chat-id (get contacts chat-id (-> chat-id
-                                                                                contact.db/public-key->new-contact
-                                                                                contact.db/enrich-contact)))
-                                    contacts)]
+ (fn [[{:keys [chat-id users contacts community-id chat-type] :as chat} mentionable-contacts blocked {:keys [name preferred-name public-key]}]]
+   (let [community-members @(re-frame/subscribe [:communities/community-members
+                                                 community-id])
+         contacts-with-one-to-one (if (= chat-type constants/one-to-one-chat-type)
+                                    (assoc mentionable-contacts chat-id (get mentionable-contacts chat-id (-> chat-id
+                                                                                contact.db/public-key->new-contact
+                                                                                contact.db/enrich-contact)))
+                                    mentionable-contacts)
+         members-left (into #{} (filter #(group-chat/member-removed? chat %) (keys users)))
+         filtered-contacts (select-keys contacts-with-one-to-one (if (nil? community-id)
+                                                                   (distinct (concat (seq contacts) (keys users) [chat-id]))
+                                                                   (keys community-members)))]
      (apply dissoc
             (-> users
-                (merge contacts-with-one-to-one)
+                (merge filtered-contacts)
                 (assoc public-key (mentions/add-searchable-phrases
                                    {:alias      name
                                     :name       (or preferred-name name)
                                     :public-key public-key})))
-            (conj blocked public-key)))))
+            (conj (concat blocked members-left) public-key)))))

 (re-frame/reg-sub
  :chat/mention-suggestions


Properly working instrument that also checks :ret

--- src/adventofcode1/spec_test_instrument_debug.clj
+++ src/adventofcode1/spec_test_instrument_debug.clj
@@ -20,8 +20,9 @@
 (in-ns 'clojure.spec.test)
 ;;(alias 'stc 'clojure.spec.test.check)

-(defn- spec-checking-fn
+(defn spec-checking-fn
   [v f fn-spec]
+  (println "spec-checking-fn")
   (let [fn-spec (@#'s/maybe-spec fn-spec)
         conform! (fn [v role spec data args]
                    (let [conformed (s/conform spec data)]
@@ -30,8 +31,8 @@
                                          stacktrace-relevant-to-instrument
                                          first)
                              ed (merge (assoc (s/explain-data* spec [role] [] [] data)
-                                         ::s/args args
-                                         ::s/failure :instrument)
+                                              ::s/args args
+                                              ::s/failure :instrument)
                                        (when caller
                                          {::caller (dissoc caller :class :method)}))]
                          (throw (ex-info
@@ -39,44 +40,110 @@
                                  ed)))
                        conformed)))]
     (fn
-     [& args]
-     (if *instrument-enabled*
-       (with-instrument-disabled
-         (let [specs fn-spec]
-           (let [cargs (when (:args specs) (conform! v :args (:args specs) args args))
-                 ret (binding [*instrument-enabled* true]
-                       (.applyTo ^clojure.lang.IFn f args))
-                 cret (when (:ret specs) (conform! v :ret (:ret specs) ret args))]
-             (when (and (:args specs) (:ret specs) (:fn specs))
-               (conform! v :fn (:fn specs) {:args cargs :ret cret} args))
-             ret)))
-       (.applyTo ^clojure.lang.IFn f args)))))
+      [& args]
+      (if *instrument-enabled*
+        (with-instrument-disabled
+          (let [specs fn-spec]
+            (let [cargs (when (:args specs) (conform! v :args (:args specs) args args))
+                  ret (binding [*instrument-enabled* true]
+                        (.applyTo ^clojure.lang.IFn f args))
+                  cret (when (:ret specs) (conform! v :ret (:ret specs) ret args))]
+              (when (and (:args specs) (:ret specs) (:fn specs))
+                (conform! v :fn (:fn specs) {:args cargs :ret cret} args))
+              ret)))
+        (.applyTo ^clojure.lang.IFn f args)))))
+
+(defn- instrument-1
+  [s opts]
+  (when-let [v (resolve s)]
+    (when-not (-> v meta :macro)
+      (let [spec (s/get-spec v)
+            {:keys [raw wrapped]} (get @instrumented-vars v)
+            current @v
+            to-wrap (if (= wrapped current) raw current)
+            ospec (or (instrument-choose-spec spec s opts)
+                      (throw (no-fspec v spec)))
+            ofn (instrument-choose-fn to-wrap ospec s opts)
+            checked (spec-checking-fn v ofn ospec)]
+        (alter-var-root v (constantly checked))
+        (swap! instrumented-vars assoc v {:raw to-wrap :wrapped checked})
+        (->sym v)))))
+
+(defn instrument
+  "Instruments the vars named by sym-or-syms, a symbol or collection
+  of symbols, or all instrumentable vars if sym-or-syms is not
+  specified.
+
+  If a var has an :args fn-spec, sets the var's root binding to a
+  fn that checks arg conformance (throwing an exception on failure)
+  before delegating to the original fn.
+
+  The opts map can be used to override registered specs, and/or to
+  replace fn implementations entirely. Opts for symbols not included
+  in sym-or-syms are ignored. This facilitates sharing a common
+  options map across many different calls to instrument.
+
+  The opts map may have the following keys:
+
+  :spec     a map from var-name symbols to override specs
+  :stub     a set of var-name symbols to be replaced by stubs
+  :gen      a map from spec names to generator overrides
+  :replace  a map from var-name symbols to replacement fns
+
+:spec overrides registered fn-specs with specs your provide. Use
+:spec overrides to provide specs for libraries that do not have
+  them, or to constrain your own use of a fn to a subset of its
+  spec'ed contract.
+
+:stub replaces a fn with a stub that checks :args, then uses the
+:ret spec to generate a return value.
+
+:gen overrides are used only for :stub generation.
+
+:replace replaces a fn with a fn that checks args conformance, then
+  invokes the fn you provide, enabling arbitrary stubbing and mocking.
+
+:spec can be used in combination with :stub or :replace.
+
+  Returns a collection of syms naming the vars instrumented."
+  ([] (instrument (instrumentable-syms)))
+  ([sym-or-syms] (instrument sym-or-syms nil))
+  ([sym-or-syms opts]
+   (locking instrumented-vars
+     (into
+      []
+      (comp (filter (instrumentable-syms opts))
+            (distinct)
+            (map #(instrument-1 % opts))
+            (remove nil?))
+      (collectionize sym-or-syms)))))
+

 ;; old definition; https://github.com/clojure/clojure/blob/0bc837b9c25ae62185795b2bf2c7952bf6e12d9e/src/clj/clojure/spec.clj
 #_(defn- spec-checking-fn
-  [v f]
-  (let [conform! (fn [v role spec data args]
-                   (let [conformed (conform spec data)]
-                     (if (= ::invalid conformed)
-                       (let [ed (assoc (explain-data* spec [role] [] [] data)
-                                  ::args args)]
-                         (throw (ex-info
-                                 (str "Call to " v " did not conform to spec:\n" (with-out-str (explain-out ed)))
-                                 ed)))
-                       conformed)))]
-    (c/fn
-     [& args]
-     (if *instrument-enabled*
-       (with-instrument-disabled
-         (let [specs (fn-specs v)]
-           (let [cargs (when (:args specs) (conform! v :args (:args specs) args args))
-                 ret (binding [*instrument-enabled* true]
-                       (.applyTo ^clojure.lang.IFn f args))
-                 cret (when (:ret specs) (conform! v :ret (:ret specs) ret args))]
-             (when (c/and (:args specs) (:ret specs) (:fn specs))
-               (conform! v :fn (:fn specs) {:args cargs :ret cret} args))
-             ret)))
-       (.applyTo ^clojure.lang.IFn f args)))))
+    [v f]
+    (let [conform! (fn [v role spec data args]
+                     (let [conformed (conform spec data)]
+                       (if (= ::invalid conformed)
+                         (let [ed (assoc (explain-data* spec [role] [] [] data)
+                                         ::args args)]
+                           (throw (ex-info
+                                   (str "Call to " v " did not conform to spec:\n" (with-out-str (explain-out ed)))
+                                   ed)))
+                         conformed)))]
+      (c/fn
+        [& args]
+        (if *instrument-enabled*
+          (with-instrument-disabled
+            (let [specs (fn-specs v)]
+              (let [cargs (when (:args specs) (conform! v :args (:args specs) args args))
+                    ret (binding [*instrument-enabled* true]
+                          (.applyTo ^clojure.lang.IFn f args))
+                    cret (when (:ret specs) (conform! v :ret (:ret specs) ret args))]
+                (when (c/and (:args specs) (:ret specs) (:fn specs))
+                  (conform! v :fn (:fn specs) {:args cargs :ret cret} args))
+                ret)))
+          (.applyTo ^clojure.lang.IFn f args)))))

 ;; 1.9-alpha14 version
 #_(defn- spec-checking-fn


Always render the header

Always render the header

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -154,9 +154,9 @@

                (when (and (= :build (:navigation-point app))
                           (project/feature-enabled? project :osx))
-             (om/build opt-in/ios-reminder-banner app))
-               (when (and (feature/enabled? :ui-v2))
-                 (om/build header/header app-without-container-data))
+                 (om/build opt-in/ios-reminder-banner app))
+
+               (om/build header/header app-without-container-data)

                [:div.app-dominant
                 (when (and inner? logged-in?)


Fix draggable for the thumbnail column.

Fix draggable for the thumbnail column.

--- src-cljs/pepa/workflows/document.cljs
+++ src-cljs/pepa/workflows/document.cljs
@@ -231,7 +231,7 @@

 (defmethod draggable/pos->width ::thumbnails [sidebars sidebar [x _]]
   (draggable/limit
-   (- x (get sidebars :root/sidebar
+   (- x (get sidebars :pepa.components.sidebar/sidebar
              css/default-sidebar-width))
    100 400))


add missing super type

add missing super type

--- src/clj/org/openforis/ceo/handler.clj
+++ src/clj/org/openforis/ceo/handler.clj
@@ -53,17 +53,19 @@
   (not (str/includes? (get headers "referer" "") (get headers "host" ""))))

 (defn- wrap-authentication [request auth-type auth-action handler]
-  (if (condp = auth-type
-        :user       (pos? (get-in request [:params :userId] -1))
-        :collect    (can-collect? request)
-        :proj-admin (is-proj-admin? request)
-        :inst-admin (is-inst-admin? request)
-        :no-cross   (is-cross-traffic? request)
-        true)
-    handler
-    (if (= :redirect auth-action)
-      (redirect-auth (get-in request [:params :userId] -1))
-      forbidden-response)))
+  (let [user-id (get-in request [:params :userId] -1)]
+    (if (condp = auth-type
+          :user       (pos? user-id)
+          :super      (= 1  user-id)
+          :collect    (can-collect? request)
+          :proj-admin (is-proj-admin? request)
+          :inst-admin (is-inst-admin? request)
+          :no-cross   (is-cross-traffic? request)
+          true)
+      handler
+      (if (= :redirect auth-action)
+        (redirect-auth user-id)
+        forbidden-response))))

 (defn routing-handler [{:keys [uri request-method] :as request}]
   (let [{:keys [auth-type auth-action handler] :as route} (get routes [request-method uri])


small fix

small fix

--- src/cljs/salava/social/ui/stream.cljs
+++ src/cljs/salava/social/ui/stream.cljs
@@ -1,23 +1,23 @@
-Loadmore (ns salava.social.ui.stream
-           (:require [salava.core.ui.layout :as layout]
-                     [reagent.session :as session]
-                     [salava.core.i18n :as i18n :refer [t translate-text]]
-                     [salava.core.ui.ajax-utils :as ajax]
-                     [reagent.core :refer [atom cursor create-class]]
-                     [salava.core.ui.modal :as mo]
-                     [salava.user.ui.helper :refer [profile-picture]]
-                     [reagent-modals.modals :as m]
-                     [salava.core.helper :refer [dump]]
-                     [salava.core.time :refer [date-from-unix-time]]
-                     [salava.user.ui.helper :refer [profile-picture]]
-            ;[salava.extra.application.ui.helper :refer [application-plugin?]]
-                     [salava.social.ui.helper :refer [system-image]]
-                     [salava.core.ui.notactivated :refer [not-activated-banner]]
-                     [salava.badge.ui.pending :refer [pending-badge-content]]
-                     [salava.core.ui.helper :refer [path-for plugin-fun not-activated? navigate-to]]
-                     [salava.badge.ui.modal :as bm]
-                     [salava.badge.ui.endorsement :refer [pending-endorsements pending-endorsement-requests]]
-                     [salava.admin.ui.helper :refer [admin?]]))
+(ns salava.social.ui.stream
+  (:require [salava.core.ui.layout :as layout]
+            [reagent.session :as session]
+            [salava.core.i18n :as i18n :refer [t translate-text]]
+            [salava.core.ui.ajax-utils :as ajax]
+            [reagent.core :refer [atom cursor create-class]]
+            [salava.core.ui.modal :as mo]
+            [salava.user.ui.helper :refer [profile-picture]]
+            [reagent-modals.modals :as m]
+            [salava.core.helper :refer [dump]]
+            [salava.core.time :refer [date-from-unix-time]]
+            [salava.user.ui.helper :refer [profile-picture]]
+   ;[salava.extra.application.ui.helper :refer [application-plugin?]]
+            [salava.social.ui.helper :refer [system-image]]
+            [salava.core.ui.notactivated :refer [not-activated-banner]]
+            [salava.badge.ui.pending :refer [pending-badge-content]]
+            [salava.core.ui.helper :refer [path-for plugin-fun not-activated? navigate-to]]
+            [salava.badge.ui.modal :as bm]
+            [salava.badge.ui.endorsement :refer [pending-endorsements pending-endorsement-requests]]
+            [salava.admin.ui.helper :refer [admin?]]))

 (defn init-data [state]
   (ajax/GET


Filter macro definitions in redundant parens

--- src/atom_finder/questions/superfluous_parens.clj
+++ src/atom_finder/questions/superfluous_parens.clj
@@ -33,7 +33,10 @@
   (let [paren-types
         [(Atom. :parens paren-node? (default-finder paren-node?))
          (Atom. :superfluous-parens superfluous-parens?
-                (default-finder #(when (paren-node? %) (superfluous-parens? %))))
+                (default-finder (fn [node]
+                                  (when (and (not (= "anonymously-parsed-code.c" (filename node)))
+                                            (paren-node? node))
+                                   (superfluous-parens? node)))))
          (atom-lookup :operator-precedence)]]
   (find-atoms paren-types root)))

@@ -66,14 +69,10 @@
        time-mins
        ))

-(defn summarize-all-parens
-  [edn-file csv-file]
-  (->>
-   ;edn-file
-   "tmp/all-parens_2018-10-28_context.edn"
-   read-lines
-   (take 10)
-   ;(maps-to-csv csv-file)
+(s/defn flatten-all-parens
+  [all-paren-lines] ; :- [{:file s/Str :parens s/Any :superfluous-parens s/Any :operator-precedence s/Any}]]
+  (->> all-paren-lines
+   ;(take 10)
    (mapcat (fn [file-map]
              (->> [:parens :superfluous-parens :operator-precedence]
                   (select-keys file-map)
@@ -82,14 +81,27 @@
                   (apply concat)
                   (map (partial into {}))
                   (map (fn [node-map]
-                         (select-keys node-map [:selection :node-type :parent-type :child-type]))))
+                         (->> [:selection :parent-type :node-type :child-type]
+                              (select-keys node-map)))))
           ))
-   (map prn)
+  )
+  )
+
+(defn summarize-all-parens
+  [edn-file csv-file]
+  (->>
+   edn-file
+   read-lines
+   ;(take 10)
+   flatten-all-parens
+   frequencies
+   (map (partial-right update-in [0] (partial map-values #(some-> % name))))
+   (map (fn [[m count]] (assoc m :count count)))
+   ;(map prn)
+   (maps-to-csv csv-file)
    time-mins
    )
   )
-
-   (select-keys {:a 1 :b 2} [:a :b])

 (defn main-superfluous-parens
   []
@@ -97,5 +109,5 @@
         csv-file "src/analysis/data/all-parens_2018-10-29_02_child.csv"
         ]
     ;(find-all-parens-in-project edn-file)
-    ;(summarize-all-nodes edn-file csv-file)
+    (summarize-all-parens edn-file csv-file)
   ))


Implement on-change for query term text

Implement on-change for query term text

--- src/cljs/cglossa/search_inputs/cwb/extended.cljs
+++ src/cljs/cglossa/search_inputs/cwb/extended.cljs
@@ -144,13 +144,12 @@
           [:span.input-group-addon.dropdown-toggle {:data-toggle "dropdown"
                                                     :style       {:cursor "pointer"}}
            [:span.glyphicon.glyphicon-menu-hamburger]]
-          [:input.form-control.multiword-field {:ref           "searchfield"
-                                                :type          "text"
-                                                :default-value (str/replace (:word term-val)
-                                                                            #"^\.\*$"
-                                                                            "")
-                                                ;:on-change     #(on-text-changed)
-                                                :on-key-down   #(on-key-down % wrapped-query)}]
+          [:input.form-control.multiword-field
+           {:ref           "searchfield"
+            :type          "text"
+            :default-value (str/replace (:form term-val) #"^\.\*$" "")
+            :on-change     #(swap! wrapped-term assoc :form (.-target.value %))
+            :on-key-down   #(on-key-down % wrapped-query)}]
           (when show-remove-term-btn?
             [:span.input-group-addon {:title    " Remove word "
                                       :style    {:cursor "pointer"}


Change `resource-columns`, et al, into maps that include the table names

In my previous commit I had changed one of the SELECT statements
to include a hard-coded list of fields (w/table names) rather than
letting it refer to the `resource-columns` set that it had been
using.  We decided that this introduced a risk of those getting
out of sync with one another, and that it would be better to
change `resource-columns` into a map that contained the table names
for each field.  This commit does that, and then modifies the other
places in the code that were using the `columns` sets to work with
the new maps.

--- src/com/puppetlabs/puppetdb/query.clj
+++ src/com/puppetlabs/puppetdb/query.clj
@@ -61,7 +61,7 @@
 ;;
 (ns com.puppetlabs.puppetdb.query
   (:require [clojure.string :as string])
-  (:use [com.puppetlabs.utils :only [parse-number]]
+  (:use [com.puppetlabs.utils :only [parse-number keyset]]
         [com.puppetlabs.puppetdb.scf.storage :only [db-serialize sql-as-numeric sql-array-query-string sql-regexp-match sql-regexp-array-match]]
         [com.puppetlabs.jdbc :only [valid-jdbc-query?]]
         [clojure.core.match :only [match]]))
@@ -133,16 +133,42 @@
     (throw (IllegalArgumentException. (format "'not' takes exactly one argument, but %d were supplied" (count terms)))))
   (negate-term* ops (first terms)))

-(def fact-columns #{"certname" "name" "value"})
-
-(def resource-columns #{"certname" "catalog" "resource" "type" "title" "tags" "exported" "sourcefile" "sourceline"})
-
-(def node-columns #{"name" "deactivated"})
-
-(def selectable-columns
-  {:resource resource-columns
-   :fact fact-columns
-   :node node-columns})
+;; This map's keys are the queryable fields for facts, and the values are the
+;;  corresponding table names where the fields reside
+(def fact-columns {"certname" "certname_facts"
+                   "name"     "certname_facts"
+                   "value"    "certname_facts"})
+
+;; This map's keys are the queryable fields for resources, and the values are the
+;;  corresponding table names where the fields reside
+(def resource-columns {"certname"   "certname_catalogs"
+                       "catalog"    "catalog_resources"
+                       "resource"   "catalog_resources"
+                       "type"       "catalog_resources"
+                       "title"      "catalog_resources"
+                       "tags"       "catalog_resources"
+                       "exported"   "catalog_resources"
+                       "sourcefile" "catalog_resources"
+                       "sourceline" "catalog_resources"})
+
+;; This map's keys are the queryable fields for nodes, and the values are the
+;;  corresponding table names where the fields reside
+(def node-columns {"name"         "certnames"
+                   "deactivated"  "certnames"})
+
+(defn column-map->sql
+  "Helper function that converts one of our column maps to a SQL string suitable
+  for use in a SELECT"
+  [col-map]
+  (string/join ", "
+    (for [[field table] col-map]
+      (str table "." field))))
+
+
+(def queryable-fields
+  {:resource (keyset resource-columns)
+   :fact     (keyset fact-columns)
+   :node     (keyset node-columns)})

 (def subquery->type
   {"select-resources" :resource
@@ -160,8 +186,8 @@
         subquery-type (subquery->type (first subquery))]
     (when-not subquery-type
       (throw (IllegalArgumentException. (format "The argument to extract must be a select operator, not '%s'" (first subquery)))))
-    (when-not (get-in selectable-columns [subquery-type field])
-      (throw (IllegalArgumentException. (format "Can't extract unknown %s field '%s'. Acceptable fields are: %s" (name subquery-type) field (string/join ", " (sort (selectable-columns subquery-type)))))))
+    (when-not (get-in queryable-fields [subquery-type field])
+      (throw (IllegalArgumentException. (format "Can't extract unknown %s field '%s'. Acceptable fields are: %s" (name subquery-type) field (string/join ", " (sort (queryable-fields subquery-type)))))))
     {:where (format "SELECT r1.%s FROM (%s) r1" field subselect)
      :params params}))

@@ -174,8 +200,8 @@
          (coll? subquery)]
    :post [(map? %)
           (string? (:where %))]}
-  (when-not (get-in selectable-columns [kind field])
-    (throw (IllegalArgumentException. (format "Can't match on unknown %s field '%s' for 'in'. Acceptable fields are: %s" (name kind) field (string/join ", " (sort (selectable-columns kind)))))))
+  (when-not (get-in queryable-fields [kind field])
+    (throw (IllegalArgumentException. (format "Can't match on unknown %s field '%s' for 'in'. Acceptable fields are: %s" (name kind) field (string/join ", " (sort (queryable-fields kind)))))))
   (when-not (= (first subquery) "extract")
     (throw (IllegalArgumentException. (format "The subquery argument of 'in' must be an 'extract', not '%s'" (first subquery)))))
   (let [{:keys [where] :as compiled-subquery} (compile-term ops subquery)]
@@ -187,7 +213,7 @@
   [ops query]
   {:post [valid-jdbc-query? %]}
   (let [{:keys [where params]} (compile-term ops query)
-        sql (format "SELECT certname_catalogs.certname, catalog_resources.catalog, catalog_resources.resource, catalog_resources.type, catalog_resources.title, catalog_resources.tags, catalog_resources.exported, catalog_resources.sourcefile, catalog_resources.sourceline FROM catalog_resources JOIN certname_catalogs ON certname_catalogs.catalog = catalog_resources.catalog WHERE %s"  where)]
+        sql (format "SELECT %s FROM catalog_resources JOIN certname_catalogs USING(catalog) WHERE %s" (column-map->sql resource-columns) where)]
     (apply vector sql params)))

 (defn fact-query->sql
@@ -196,7 +222,7 @@
   [ops query]
   {:post [valid-jdbc-query? %]}
   (let [{:keys [where params]} (compile-term ops query)
-        sql (format "SELECT %s FROM certname_facts WHERE %s" (string/join ", " (map #(str "certname_facts." %) fact-columns)) where)]
+        sql (format "SELECT %s FROM certname_facts WHERE %s" (column-map->sql fact-columns) where)]
     (apply vector sql params)))

 (defn node-query->sql
@@ -205,7 +231,7 @@
   [ops query]
   {:post [valid-jdbc-query? %]}
   (let [{:keys [where params]} (compile-term ops query)
-        sql (format "SELECT %s FROM certnames WHERE %s" (string/join ", " node-columns) where)]
+        sql (format "SELECT %s FROM certnames WHERE %s" (column-map->sql node-columns) where)]
     (apply vector sql params)))

 (defn compile-resource-equality-v2


Adds divide

Adds divide

--- src/the_little_clojurian/chapter4.clj
+++ src/the_little_clojurian/chapter4.clj
@@ -148,3 +148,15 @@
   (is (= (expt 2 2) 4))
   (is (= (expt 2 3) 8))
   (is (= (expt 5 3) 125)))
+
+(with-test
+  (def divide
+    (fn [n m]
+      (cond (zero? m) (throw (IllegalArgumentException.))
+            (smaller-than n m) 0
+            :else (add1 (divide (minuss n m) m)))))
+  (is (= (divide 0 1) 0))
+  (is (thrown? IllegalArgumentException (divide 1 0)))
+  (is (= (divide 15 4) 3))
+  (is (= (divide 15 3) 5))
+  (is (= (divide 100 10) 10)))


less fragile icon centering using flex justify and align. multiple layouts new layout algorithm (version **)

--- src/unspun/screens/number_needed.cljs
+++ src/unspun/screens/number_needed.cljs
@@ -14,22 +14,18 @@
     :or   {size 100 draw? true key nil}}]
   (view {:key   key
          :style {:backgroundColor "orange"
-                 :paddingTop 1
+                 :paddingTop      1
                  :aspectRatio     1
                  :opacity         (if draw? 1 0)
-                 :justifyContent  "space-around"
+                 :flexDirection   "column"
+                 :justifyContent  "center"
                  :alignItems      "center"
                  :width           size                      ;size
                  :borderRadius    (/ size 2)
                  }}
         (view
-          {:style {:transform (clj->js [{:translateX 10}
-                                        {:translateY -99}
-                                        {:scale (/ size 100)}
-                                        {:translateX (/ (* -9 100) size)}
-                                        {:translateY (/ (* 100 100) size)}
-                                        ])}}
-          (ionicon {:name  "ios-wine"                      ;"ios-radio-button-on"
+          {:style {:transform (clj->js [{:scale (/ size 100)}])}}
+          (ionicon {:name  "ios-wine"                       ;"ios-radio-button-on"
                     :size  100
                     :style {:width           100
                             :textAlign       "center"
@@ -61,7 +57,7 @@
                   (draw-square {:size 50}))))
         ))

-(def testn 40)
+(def testn 6)

 (def row0 [0 0 0 0 0])
 (def row1 [0 0 1 0 0])
@@ -69,21 +65,26 @@
 (def row3 [1 0 1 0 1])
 (def row4 [1 1 0 1 1])
 (def row5 [1 1 1 1 1])
-(def row10 (vec (concat row5 [0] row5)))
+
+(def row10 "row of 10" (vec (concat row5 [0] row5)))
+(def row15 "row of 15" (vec (concat row5 [0] row5 [0] row5)))
 (def rown [row0 row1 row2 row3 row4 row5])
-(def block10 [row5 row5])
-(defn append-block [b n] (if (< n 6)
-                           (conj b row0 (rown n))
-                           (conj (append-block b 5) (rown (- n 5)))))
+
+(def block10 "two rows of 5" [row5 row5])
+
+(defn append-block [b n] (into [] (if (< n 6)
+                                    (conj b row0 (rown n))
+                                    (conj (append-block b 5) (rown (- n 5))))))
+
 (def block20 (append-block block10 10))
 (def block30 (append-block block20 10))
 ;(def block40 (append-block block30 10))

-(def block40 (into [] (-> nil
-                         (append-block 8)
-                         (append-block 10)
-                         (append-block 10)
-                         (append-block 10))))
+(def block40 (into [] (next (-> []
+                                (append-block 10)
+                                (append-block 10)
+                                (append-block 10)
+                                (append-block 8)))))

 (def dice {1  [[1]]
            2  [[1 0]
@@ -96,7 +97,7 @@
                [0 1 0]
                [1 0 1]]
            6  [[1 1 1]
-               [0 0 0]
+               nil
                [1 1 1]]
            7  [[1 1 0]
                [1 1 1]
@@ -107,19 +108,55 @@
            9  [[1 1 1]
                [1 1 1]
                [1 1 1]]
-           10 block10
-           11 (append-block block10 1)
-           12 (append-block block10 2)
-           13 (append-block block10 3)
-           14 (append-block block10 4)
-           15 (append-block block10 5)
-           16 (append-block block10 6)
-           17 (append-block block10 7)
-           18 (append-block block10 8)
-           19 (append-block block10 9)
-           20 block20
-           21 (append-block block20 1)
-           22 (append-block block20 2)
+           10 [row5
+               row5]
+           11 [row5
+               row5
+               nil
+               row1]
+           12 [row5
+               row5
+               nil
+               row2]
+           13 [row5
+               row5
+               nil
+               row3]
+           14 [row5
+               row5
+               nil
+               row4]
+           15 [row5
+               row5
+               nil
+               row5]
+           16 [row5
+               row5
+               nil
+               row5
+               row1]
+           17 [row5
+               row5
+               nil
+               row5
+               row2]
+           18 [row5
+               row5
+               nil
+               row5
+               row3]
+           19 [row5
+               row5
+               nil
+               row5
+               row4]
+           20 [row5
+               row5
+               nil
+               row5
+               row5]
+           21 [row10 row10 nil row10 row10 nil [1 1 1 1 1 0 1 1 1 1 0]]
+           22 [row15 row15 nil row15 row15 nil row15 row15 nil row15 row15 nil row15 row15 nil row15 row15 nil row15 row15 nil row15 row15 nil row15 row15 nil row15 row15 nil row15 row15]
            23 (append-block block20 3)
            24 (append-block block20 4)
            25 (append-block block20 5)
@@ -144,16 +181,60 @@
   "layout n icons in an easy to count manner (dice-like for small n)"
   [n]
   (cond
-    (< n 10) (get dice n)
-    (< n 20) (append-block block10 n)
+    (< n 23) (get dice n)
+    (< n 24) (append-block block10 n)
     (< n 30) (append-block block20 n)
     (< n 40) (append-block block30 n)
     :else (append-block block40 0)
     ))

+(defn icon-top
+  "Determine vertical position of icons, taking account of their size a, the layout for the number n,
+  and the row number i"
+  [i a n]
+  (- (* i a) (cond
+               (> n 9)
+               (* 2 (quot i 3) (/ a 3))
+
+               (= n 6)
+               (condp = i
+                 0 (- (/ a 3))
+                 1 0
+                 2 (* 2 (/ a 3))
+                 3 0)
+               :else 0)))
+
+(rum/defc nested-n-square** < rum/static
+  [w h n]
+  (let [padding 10
+        cols (count ((dicen n) 0))
+        rows (count (dicen n))
+        a (/ (- w (* 2 padding)) cols)]
+    (view {:style {;:flexDirection     "column"
+                   :flex    0
+                   :width   w
+                   :height  (+ (* 2 padding) (icon-top (count (dicen n)) a n))
+                   :padding padding
+                   ;:justifyContent    "space-around"
+                   }}
+          (for [[i row] (zipmap (range) (dicen n))]
+            (view {:key   (str "r" i)
+                   :style {:flex     0
+                           :position "relative"}}
+                  (when row
+                    (for [[j col] (zipmap (range) row)]
+                      (view {:style {:position "absolute"
+                                     :top      (icon-top i a n)
+                                     :left     (* j a)}}
+                            (draw-square {:size  a
+                                          :draw? (not (zero? col))
+                                          :key   (str "c" j)})))
+                    )))))
+  )
+
 (rum/defc nested-n-square* < rum/static
   [w h n]
-  (let [padding 20
+  (let [padding 10
         cols (count ((dicen n) 0))
         rows (count (dicen n))
         a (/ (- w (* 2 padding)) cols)]
@@ -164,12 +245,14 @@
                    :justifyContent    "space-around"
                    :borderBottomWidth 1
                    :borderBottomColor "black"}}
-          (for [[i row] (zipmap (range) (dicen n))]
+          (for [[i row] (zipmap (range) (dicen n))
+                :let [row (if (nil? row) [0 0 0 0 0] row)
+                      gap? (or (nil? row) (= row [0 0 0 0 0]))]]
             (view {:key   (str "r" i)
                    :style {:flexDirection  "row"
                            :justifyContent "space-around"}}
                   (for [[j col] (zipmap (range) row)]
-                    (draw-square {:size  (if (zero? col) (/ a 3) a)
+                    (draw-square {:size  (if (or gap? (and (not (zero? j)) (zero? (mod j 5)) (zero? col))) (/ a 3) a)
                                   :draw? (not (zero? col))
                                   :key   (str "c" j)})))))))

@@ -279,7 +362,7 @@
                          (view {:style {:flex           1
                                         :flexDirection  "column"
                                         :justifyContent "flex-start"}}
-                               (nested-n-square* w h testn)
+                               (nested-n-square** w h testn)
                                #_(view {:style {:flexDirection     "column"
                                                 :height            w
                                                 :justifyContent    "space-around"


Add key/encode nil tests.

Add key/encode nil tests.

--- test/merkle_db/key_test.clj
+++ test/merkle_db/key_test.clj
@@ -153,6 +153,9 @@
         "should not accept any config parameters"))
   (testing "bad values"
     (is (thrown? IllegalArgumentException
+          (key/encode key/bytes-lexicoder nil))
+        "should not encode nil")
+    (is (thrown? IllegalArgumentException
           (key/encode key/bytes-lexicoder "foo"))
         "should not encode non-byte-arrays")
     (is (thrown? IllegalArgumentException
@@ -186,6 +189,9 @@
         "should only accept one config parameter"))
   (testing "bad values"
     (is (thrown? IllegalArgumentException
+          (key/encode key/string-lexicoder nil))
+        "should not encode nil")
+    (is (thrown? IllegalArgumentException
           (key/encode key/string-lexicoder 123))
         "should not encode non-strings")
     (is (thrown? IllegalArgumentException
@@ -212,6 +218,9 @@
           (key/lexicoder [:integer :bar]))
         "should not accept any config parameters"))
   (testing "bad values"
+    (is (thrown? IllegalArgumentException
+          (key/encode key/integer-lexicoder nil))
+        "should not encode nil")
     (is (thrown? IllegalArgumentException
           (key/encode key/integer-lexicoder 0.0))
         "should not encode non-integers")
@@ -238,6 +247,9 @@
         "should not accept any config parameters"))
   (testing "bad values"
     (is (thrown? IllegalArgumentException
+          (key/encode key/float-lexicoder nil))
+        "should not encode nil")
+    (is (thrown? IllegalArgumentException
           (key/encode key/float-lexicoder 123))
         "should not encode non-floats")
     (is (thrown? IllegalArgumentException
@@ -263,6 +275,9 @@
         "should not accept any config parameters"))
   (testing "bad values"
     (is (thrown? IllegalArgumentException
+          (key/encode key/instant-lexicoder nil))
+        "should not encode nil")
+    (is (thrown? IllegalArgumentException
           (key/encode key/instant-lexicoder ""))
         "should not encode non-instant value")))

@@ -283,6 +298,9 @@
           (key/lexicoder [:seq :string :foo]))
         "should only accept one config parameter"))
   (testing "bad values"
+    (is (thrown? IllegalArgumentException
+          (key/encode (key/sequence-lexicoder key/integer-lexicoder) nil))
+        "should not encode nil")
     (is (thrown? IllegalArgumentException
           (key/encode (key/sequence-lexicoder key/integer-lexicoder) #{123}))
         "should not encode non-sequential values")))
@@ -309,6 +327,9 @@
         "should require at least one config parameter"))
   (testing "bad values"
     (is (thrown? IllegalArgumentException
+          (key/encode (key/tuple-lexicoder key/integer-lexicoder) nil))
+        "should not encode nil")
+    (is (thrown? IllegalArgumentException
           (key/encode (key/tuple-lexicoder key/integer-lexicoder) #{123}))
         "should not encode non-sequential values")
     (is (thrown? IllegalArgumentException


test only variants

test only variants

--- src/wb_es/bulk/core.clj
+++ src/wb_es/bulk/core.clj
@@ -137,10 +137,15 @@

 (defn schedule-jobs-sample [db]
   ;; schedule something for testing
-  (let [eids (get-eids-by-type db :analysis/id)
-        jobs (make-batches 1000 :analysis eids)]
+  ;; (let [eids (get-eids-by-type db :analysis/id)
+  ;;       jobs (make-batches 1000 :analysis eids)]
+  ;;   (doseq [job jobs]
+  ;;     (scheduler-put! job)))
+  (let [eids (get-eids-by-type db :variation/id)
+        jobs (make-batches 1000 :variation eids)]
     (doseq [job jobs]
       (scheduler-put! job)))
+
   )

 (defn schedule-jobs-all [db]
@@ -384,7 +389,7 @@
                     :delete-existing true)
       (let [db (d/db datomic-conn)]
         (do
-          (schedule-jobs-all db)
+          (schedule-jobs-sample db)
           (connect-snapshot-repository repository-name)
           (scheduler-put! (with-meta {} {:action "snapshot"
                                          :index index-id


allow a revision number to be provided for indecies build from the same release

--- src/wb_es/bulk/core.clj
+++ src/wb_es/bulk/core.clj
@@ -101,11 +101,12 @@
        )
   )

-(defn run [& {:keys [db]
-              :or {db (d/db datomic-conn)}}]
-  (let [index-id (format "%s_v0" release-id)]
+(defn run [& {:keys [db index-revision-number]
+              :or {db (d/db datomic-conn)
+                   index-revision-number 0}}]
+  (let [index-id (format "%s_v%s" release-id index-revision-number)]
     (do
-      (create-index index-id :default-index true)
+      (create-index index-id :default-index (= index-revision-number 0))
       (let [n-threads 4
             scheduler (chan n-threads)
             logger (chan n-threads)]
@@ -333,11 +334,15 @@
           (close! scheduler))
         ))))

+
 (defn -main
   "I don't do a whole lot ... yet."
   [& args]
   (do
-    (println "Hello, Bulky World!")
+    (println "Indexer starting!")
     (mount/start)
-    (run)
-    (mount/stop)))
+    (if-let [index-revision-number (first args)]
+      (run :index-revision-number index-revision-number)
+      (run))
+    (mount/stop))
+  )


Update org.apache.tika/tika-core && tika-parsers  to "1.21"

--- backend/project.clj
+++ backend/project.clj
@@ -26,8 +26,8 @@
                  [metosin/reitit "0.3.7" :exclusions [com.cognitect/transit-java org.clojure/spec.alpha org.ow2.asm/asm ring/ring-core mvxcvi/puget org.clojure/clojure ring/ring-codec org.clojure/core.rrb-vector mvxcvi/arrangement fipp r org.clojure/core.specs.alpha com.cognitect/transit-clj com.fasterxml.jackson.core/jackson-databind com.fasterxml.jackson.core/jackson-core]]
                  [org.akvo/commons "0.4.6" :exclusions [org.postgresql/postgresql org.clojure/java.jdbc]]
                  [org.akvo/resumed "1.46.266acfa5bb52c9b484af19f0bcfbfacb60b97319"]
-                 [org.apache.tika/tika-core "1.18"]
-                 [org.apache.tika/tika-parsers "1.18" :exclusions [org.slf4j/slf4j-api com.fasterxml.jackson.core/jackson-core org.apache.httpcomponents/httpcore org.apache.httpcomponents/httpclient org.apache.httpcomponents/httpmime]]
+                 [org.apache.tika/tika-core "1.21"]
+                 [org.apache.tika/tika-parsers "1.21" :exclusions [org.slf4j/slf4j-api com.fasterxml.jackson.core/jackson-core org.apache.httpcomponents/httpcore org.apache.httpcomponents/httpclient org.apache.httpcomponents/httpmime]]
                  ;; explicit versions of commons deps used by tika-parsers and clj-http
                  [com.fasterxml.jackson.core/jackson-core "2.9.6"]
                  [org.apache.httpcomponents/httpcore "4.4.10"]


Version 1.2.0

Version 1.2.0

--- backend/project.clj
+++ backend/project.clj
@@ -1,4 +1,4 @@
-(defproject lambdaui "1.2.0-SNAPSHOT"
+(defproject lambdaui "1.2.0"
   :description "LambdaCD-Plugin that provides a modern UI for your pipeline."
   :url "https://github.com/sroidl/lambda-ui"
   :license {:name "Apache License 2.0"


refactor player attack func

refactor player attack func

--- src/zombie_run/game.clj
+++ src/zombie_run/game.clj
@@ -72,25 +72,28 @@
                 :direction direction}))))

 (defn- player-attack [{terrain :terrain world-size :world-size :as game} player-pos]
-  (if-let [target-pos (reduce (fn [_ counter]
-                                (let [target-pos (world/get-position world-size
-                                                                     player-pos
-                                                                     (terrain/get-property terrain player-pos :direction)
-                                                                     counter)]
-                                  (when (terrain/has-type? terrain target-pos :zombie)
-                                    (reduced target-pos))))
-                              nil
-                              (range 1 (inc (weapon/weapon-range (get-in terrain [player-pos :weapon])))))]
-    (let [[weapon damage] (weapon/fire-weapon
-                            (terrain/get-property terrain player-pos :weapon))]
-      (assoc game :terrain (-> terrain
-                               (terrain/set-property player-pos :weapon weapon)
-                               (terrain/damage target-pos damage))))
-    (update game :terrain
-            terrain/update-property
-            player-pos
-            :weapon
-            weapon/weapon-reset-recharge)))
+  (let [player-direction (terrain/get-property terrain player-pos :direction)
+        player-weapon (terrain/get-property terrain player-pos :weapon)
+        find-target (fn [_ counter]
+                      (let [target-pos (world/get-position world-size
+                                                           player-pos
+                                                           player-direction
+                                                           counter)]
+                        (when (terrain/has-type? terrain target-pos :zombie)
+                          (reduced target-pos))))
+        weapon range]
+    (if-let [target-pos (reduce find-target
+                                nil
+                                (range 1 (inc (weapon/weapon-range player-weapon))))]
+      (let [[weapon damage] (weapon/fire-weapon player-weapon)]
+        (assoc game :terrain (-> terrain
+                                 (terrain/set-property player-pos :weapon weapon)
+                                 (terrain/damage target-pos damage))))
+      (update game :terrain
+              terrain/update-property
+              player-pos
+              :weapon
+              weapon/weapon-reset-recharge))))
 ;;
 ;; zombie
 ;;


add tests for custom readers/writers

add tests for custom readers/writers

--- test/transit/test/core.cljs
+++ test/transit/test/core.cljs
@@ -105,4 +105,30 @@
 (assert (= (t/read (t/reader :json {:handlers {"custom" (fn [x] x)}}) "[\"~:foo\", 1]")
            [:foo 1]))

+(defrecord Point [x y])
+
+(deftype PointHandler []
+  Object
+  (tag [_ v] "point")
+  (rep [_ v] #js [(.-x v) (.-y v)])
+  (stringRep [_ v] nil))
+
+(def cr (t/reader :json
+          {:handlers
+           {"custom" (fn [x] x)
+            "point" (fn [[x y]] (Point. x y))}}))
+
+(assert (= (t/read cr "[\"~#point\",[1.5,2.5]]")
+           (Point. 1.5 2.5)))
+
+(assert (= (t/read cr "[\"~:foo\", 1]")
+           [:foo 1]))
+
+(def cw (t/writer :json
+          {:handlers
+           {Point (PointHandler.)}}))
+
+(assert (= (t/write cw (Point. 1.5 2.5))
+           "[\"~#point\",[1.5,2.5]]"))
+
 (println "ok")


gah! fix horrible beeminder bug

gah! fix horrible beeminder bug

Rather than checking to see whether a ping occurred within the past
week, I was checking to see whether it'd occurred today, 24 days ago, 48
days ago, ... up to 7*24 days ago. Oops.

--- src/clj/tictag/beeminder.clj
+++ src/clj/tictag/beeminder.clj
@@ -56,7 +56,7 @@
                    :query-params {:auth_token auth-token}})))

 (defn past-week-days []
-  (set (map db/local-day (take 7 (p/periodic-seq (t/now) (t/days -24))))))
+  (set (map db/local-day (take 7 (p/periodic-seq (t/now) (t/days -1))))))

 (defn days-matching-tag [tags rows]
   (->> rows
@@ -79,9 +79,7 @@
                 existing-datapoints      (filter
                                           #(in-past-week? (:daystamp %))
                                           (datapoints
-                                           (get-in
-                                            user
-                                            [:beeminder :token])
+                                           token
                                            username
                                            name))
                 existing-map             (group-by :daystamp existing-datapoints)


Whitespace.

Whitespace.


Add more comments to horrible sample code.


#1 Got to the point that the WAR is resolved through maven


more dox cleanup

more dox cleanup

--- src/metabase/api/session.clj
+++ src/metabase/api/session.clj
@@ -83,8 +83,8 @@
   (swap! failed-login-attempts conj [email (java.util.Date.)]))

 (defn- calculate-login-delay
-  "Calculate the appropriate delay (in seconds) before a user should be allowed to login again based on MOST-RECENT-ATTEMPT
-   and NUM-RECENT-ATTEMPTS. This function returns `nil` if there is no delay that should be required."
+  "Calculate the appropriate delay (in seconds) before a user should be allowed to login again based on
+   MOST-RECENT-ATTEMPT and NUM-RECENT-ATTEMPTS. This function returns `nil` if there is no delay that should be required."
   [^java.util.Date most-recent-attempt num-recent-attempts]
   (when most-recent-attempt
     (assert (= (type most-recent-attempt) java.util.Date))


release and update version

release and update version

--- clj-tcp/project.clj
+++ clj-tcp/project.clj
@@ -1,4 +1,4 @@
-(defproject clj-tcp "0.4.4-SNAPSHOT"
+(defproject clj-tcp "0.4.5-SNAPSHOT"
   :description "Fast clojure tcp library based on netty"
   :url "https://github.com/gerritjvv/clj-tcp"
   :license {:name "Eclipse Public License"