Use constants on workspace settings lightbox.

--- src/uxbox/ui/workspace/settings.cljs
+++ src/uxbox/ui/workspace/settings.cljs
@@ -9,6 +9,7 @@
   (:require [sablono.core :as html :refer-macros [html]]
             [lentes.core :as l]
             [rum.core :as rum]
+            [uxbox.constants :as c]
             [uxbox.rstore :as rs]
             [uxbox.data.pages :as udp]
             [uxbox.ui.icons :as i]
@@ -55,15 +56,14 @@
          [:input#grid-x.input-text
           {:placeholder "X px"
            :type "number"
-           ;; TODO: put here the default from constants
-           :value (:grid/x-axis opts "10")
+           :value (:grid/x-axis opts c/grid-x-axis)
            :on-change (partial on-field-change :grid/x-axis)
-           :min 1 ;;TODO check this value
+           :min 1
            :max 100}]
          [:input#grid-y.input-text
           {:placeholder "Y px"
            :type "number"
-           :value (:grid/y-axis opts "10")
+           :value (:grid/y-axis opts c/grid-y-axis)
            :on-change (partial on-field-change :grid/y-axis)
            :min 1
            :max 100}]]


Add version to atom

Add version to atom

--- src/yada/resources/atom_resource.clj
+++ src/yada/resources/atom_resource.clj
@@ -12,16 +12,19 @@

 (defn string-atom-resource [*a]
   (let [*last-modified (atom (to-date (now)))
-        val (as-resource @*a)]
+        val (as-resource @*a)
+        *version (atom @*a)]
     (add-watch
      *a :last-modified
-     (fn [_ _ _ _]
-       (reset! *last-modified (to-date (now)))))
+     (fn [_ _ _ s]
+       (reset! *last-modified (to-date (now)))
+       (reset! *version s)))
     (resource
      (merge
       (when-let [produces (:produces val)]
         {:produces produces})
-      {:properties (fn [ctx] {:last-modified @*last-modified})
+      {:properties (fn [ctx] {:last-modified @*last-modified
+                              :version @*version})
        :methods {:get (merge (get-in val [:methods :get])
                              {:description "Derefrence to get the value of the atom"
                               :summary "Get the atom's value"


[suite/inference] Fix a few typos. (#61)

- gpu could never be used because of compote -> compute
 - batch size was hard coded to `1`
 - tiny improvement to a docstring.

--- suite/src/cortex/suite/inference.clj
+++ suite/src/cortex/suite/inference.clj
@@ -17,7 +17,7 @@
                      (or (when-not force-cpu?
                            (try
                              (require 'think.compute.nn.cuda-backend)
-                             ((resolve 'think.compote.nn.cuda-backend/create-backend) datatype)
+                             ((resolve 'think.compute.nn.cuda-backend/create-backend) datatype)
                              (catch Exception e
                                (println (format "Failed to create cuda backend (%s); will use cpu backend"
                                                 e))
@@ -42,13 +42,12 @@
                       {:batch-size batch-size
                        :observation-count (count observations)})))
     (as-> (traverse/auto-bind-io network) network-or-seq
-      (execute/infer-columns context network-or-seq dataset [] [] :batch-size 1)
+      (execute/infer-columns context network-or-seq dataset [] [] :batch-size batch-size)
       (get network-or-seq (first leaves)))))

 (defn classify-one-observation
-  "data-shape is
-(ds/create-image-shape num-channels img-width img-height)"
+  "observation-dataset-shape is something like (ds/create-image-shape num-channels img-width img-height)"
   [network observation observation-dataset-shape class-names]
   (let [results (infer-n-observations network [observation] observation-dataset-shape
                                       :batch-size 1


Less noise.

Less noise.

--- integration-tests/src/test/clojure/immutant/integs/sessions.clj
+++ integration-tests/src/test/clojure/immutant/integs/sessions.clj
@@ -38,7 +38,7 @@
   (when-let [result (client/get
                      (str "http://localhost:8080/sessions/" sub-path "?" query-string)
                      {:cookies @cookies})]
-    (println "RESULT:" result)
+    ;; (println "RESULT:" result)
     (if (get-in result [:cookies "JSESSIONID"])
       (reset! cookies (:cookies result)))
     (read-string (:body result))))


Fix arity.

Fix arity.

--- test/cljx/snippets/shape/curves.cljx
+++ test/cljx/snippets/shape/curves.cljx
@@ -5,12 +5,25 @@
   #+cljs
   (:use-macros [quil.snippet :only [defsnippet]]))

+#+clj
 (defsnippet bezier {:renderer :p3d}
   (q/camera 200 200 200 0 0 0 0 0 -1)
   (q/no-fill)
   (q/bezier 0 0 50 100 100 -100 150 0)
   (q/bezier 0 0 0 0 100 0 0 100 0 100 0 0))

+#+cljs
+(defsnippet bezier-2d {}
+  (q/no-fill)
+  (q/bezier 0 0 50 100 100 -100 150 0))
+
+#+cljs
+(defsnippet bezier-3d {:renderer :p3d}
+  (q/camera 200 200 200 0 0 0 0 0 -1)
+  (q/no-fill)
+  (q/bezier 0 0 0 0 100 0 0 100 0 100 0 0))
+
+#+clj
 (defsnippet bezier-detail {:renderer :p3d}
   (q/camera 0 0 300 0 0 0 0 1 0)
   (q/no-fill)
@@ -18,6 +31,19 @@
   (q/bezier 0 0 50 100 100 -100 150 0)
   (q/bezier-detail 20)
   (q/bezier 0 0 -50 100 -100 -100 -150 0))
+
+#+cljs
+(defsnippet bezier-detail-2d {}
+  (q/no-fill)
+  (q/bezier-detail 5)
+  (q/bezier 0 0 50 100 100 -100 150 0))
+
+#+cljs
+(defsnippet bezier-detail-3d {:renderer :p3d}
+  (q/camera 0 0 300 0 0 0 0 1 0)
+  (q/no-fill)
+  (q/bezier-detail 20)
+  (q/bezier 0 0 0 0 100 0 0 100 0 100 0 0))

 (defsnippet bezier-point {}
   (q/fill 0)


Add failing test for how :ORDERED: works I think

--- org-mode/test/com/gfredericks/org_agenda_test.clj
+++ org-mode/test/com/gfredericks/org_agenda_test.clj
@@ -75,3 +75,20 @@
        now
        (fn [agenda]
          (is (= 20 (count (re-seq #"just appear once" agenda)))))))))
+
+(deftest ordered-test
+  (do-integration
+   {"only-file.org"
+    (str "* Hello\n"
+         "  :PROPERTIES:\n"
+         "  :ORDERED: t\n"
+         "  :END:\n"
+         "** TODO Aaa\n"
+         "*** TODO Bbb\n"
+         "** TODO Ccc\n"
+         "*** TODO Ddd\n")}
+   ;; doesn't matter
+   (ZonedDateTime/of 2022 7 10 16 22 15 0 oa/CHICAGO)
+   (fn [agenda]
+     (is (= 1 (count (re-seq #"TODO" agenda))))
+     (is (re-find #"Bbb" agenda)))))


make :dev-http properly handle index files in classpath roots

fixes #1064

--- src/main/shadow/http/push_state.clj
+++ src/main/shadow/http/push_state.clj
@@ -1,6 +1,7 @@
 (ns shadow.http.push-state
-  (:require [clojure.java.io :as io]
-            [clojure.string :as str]))
+  (:require
+    [clojure.java.io :as io]
+    [clojure.string :as str]))

 (def not-found
   {:status 404
@@ -20,9 +21,12 @@
             index-file
             (reduce
               (fn [_ http-root]
-                (let [file (io/file http-root index-name)]
-                  (when (and file (.exists file))
-                    (reduced file))))
+                (if (str/starts-with? http-root "classpath:")
+                  (when-some [rc (io/resource (str (subs http-root 10) "/" index-name))]
+                    (reduced rc))
+                  (let [file (io/file http-root index-name)]
+                    (when (and file (.exists file))
+                      (reduced file)))))
               nil
               http-roots)]


add type hints to avoid reflection

add type hints to avoid reflection

--- pigpen-avro/src/main/clojure/pigpen/avro/core.clj
+++ pigpen-avro/src/main/clojure/pigpen/avro/core.clj
@@ -21,11 +21,14 @@
             [pigpen.raw :as raw]
             [pigpen.core :as pig])
   (:import [org.apache.avro
+            Schema
+            Schema$Field
             Schema$Type
             Schema$Parser
             SchemaNormalization]
            [org.apache.avro.file DataFileReader]
            [org.apache.avro.specific SpecificDatumReader]
+           [org.apache.avro.generic GenericData$Record]
            [pigpen.local PigPenLocalLoader]))

 (set! *warn-on-reflection* true)
@@ -35,15 +38,15 @@
   (for [subfield (field-names record-schema)]
     (str prefix "." subfield)))

-(defn field-names [parsed-schema]
+(defn field-names [^Schema parsed-schema]
  (->> (.getFields parsed-schema)
-       (map (fn [field]
-              (let [type (.getType (.schema field))]
+       (map (fn [^Schema$Field field]
+              (let [type (.getType ^{:tag Schema} (.schema field))]
                 (cond
                  (= type Schema$Type/RECORD) (prefixed-names (.schema field) (.name field))
                  ;; pig only supports union of null, <type>.
                  (= type Schema$Type/UNION)  (let [record-fields (->> (.getTypes (.schema field))
-                                                                      (filter #(= (.getType %) Schema$Type/RECORD))
+                                                                      (filter #(= (.getType ^{:tag Schema} %) Schema$Type/RECORD))
                                                                       (map (fn [rec] (prefixed-names rec (.name field)))))]
                                                (if (empty? record-fields) [(.name field)]
                                                    record-fields))
@@ -51,7 +54,8 @@
        flatten
        vec))

-(defn parse-schema [s] (.parse (Schema$Parser.) s))
+(defn parse-schema [^String s] (let [parser ^Schema$Parser (Schema$Parser.)]
+                         (.parse parser s)))

 (defmethod pigpen.pig/native->clojure org.apache.avro.util.Utf8 [value]
   (str value))
@@ -82,7 +86,7 @@

 "
   ([location schema]
-     (let [parsed-schema (parse-schema schema)
+     (let [^Schema parsed-schema (parse-schema schema)
            storage (raw/storage$
                     ["piggybank.jar"]
                     "org.apache.pig.piggybank.storage.avro.AvroStorage"
@@ -98,19 +102,19 @@
          {:args (clojure.core/mapcat (juxt str identity) field-symbols)
           :field-type-in :native })))))

-(defn attrs-lookup [record attr-names]
+(defn attrs-lookup [^GenericData$Record record attr-names]
   (cond
    (nil? record) nil
    (empty? attr-names) record
-   :else (attrs-lookup (.get record (first attr-names)) (rest attr-names))))
+   :else (attrs-lookup (.get record ^{:tag java.lang.String} (first attr-names)) (rest attr-names))))

 (defmethod pigpen.local/load "org.apache.pig.piggybank.storage.avro.AvroStorage"
   [{:keys [location fields] }]
   (reify PigPenLocalLoader
     (locations [_] (pigpen.local/load-list location))
     (init-reader [_ filename]
-      (-> filename (java.io.File.) (DataFileReader. (SpecificDatumReader.))))
+      (-> ^java.lang.String filename (java.io.File.) (DataFileReader. (SpecificDatumReader.))))
     (read [_ reader]
-      (for [datum reader]
+      (for [datum ^SpecificDatumReader reader]
         (zipmap fields (map #(attrs-lookup datum (str/split (name %) #"\.")) fields))))
-    (close-reader [_ reader] (.close reader))))
+    (close-reader [_ reader] (.close ^{:tag java.io.Closeable} reader))))


build real cascading flow

build real cascading flow

--- pigpen-core/src/main/clojure/pigpen/cascading.clj
+++ pigpen-core/src/main/clojure/pigpen/cascading.clj
@@ -1,7 +1,8 @@
 (ns pigpen.cascading
   (:import (cascading.tap.hadoop Hfs)
            (cascading.scheme.hadoop TextLine)
-           (cascading.pipe Pipe))
+           (cascading.pipe Pipe)
+           (cascading.flow.hadoop HadoopFlowConnector))
   (:require [pigpen.raw :as raw]))

 (defn- get-tap-fn [name]
@@ -30,10 +31,9 @@
 (defmethod command->flowdef :store
            [{:keys [id ancestors location storage opts]} flowdef]
   {:pre [id ancestors location storage]}
-  (let [tap ((get-tap-fn (:func storage)) location)]
-    (-> flowdef
-        (update-in [:pipe-to-sink] (partial merge {(first ancestors) tap}))
-        (update-in [:sinks] (partial merge {id tap})))))
+  (-> flowdef
+      (update-in [:pipe-to-sink] (partial merge {(first ancestors) id}))
+      (update-in [:sinks] (partial merge {id ((get-tap-fn (:func storage)) location)}))))

 (defmethod command->flowdef :generate
            [{:keys [id ancestors projections opts]} flowdef]
@@ -41,7 +41,7 @@
   (if (contains? (:sources flowdef) (first ancestors))
     (let [pipe (Pipe. (str id))]
       (-> flowdef
-          (update-in [:source-to-pipe] (partial merge {(first ancestors) pipe}))
+          (update-in [:pipe-to-source] (partial merge {id (first ancestors)}))
           (update-in [:pipes] (partial merge {id pipe}))))
     (throw (Exception. "not implemented"))))

@@ -52,6 +52,15 @@
 (defn commands->flow
   "Transforms a series of commands into a Cascading flow"
   [commands]
-  (let [flowdef (reduce (fn [def cmd] (command->flowdef cmd def)) {} commands)]
+  (let [flowdef (reduce (fn [def cmd] (command->flowdef cmd def)) {} commands)
+        {:keys [pipe-to-source sources pipe-to-sink sinks pipes]} flowdef
+        sources-map (into {} (map (fn [[p s]] [(str p) (sources s)]) pipe-to-source))
+        sinks-map (into {} (map (fn [[p s]] [(str p) (sinks s)]) pipe-to-sink))
+        tail-pipes (into-array Pipe (map #(pipes %) (keys pipe-to-sink)))]
+
+    (println sources-map)
+    (println sinks-map)
+    (println tail-pipes)
+    (.connect (HadoopFlowConnector.) sources-map sinks-map tail-pipes)
     flowdef))


A nice chunk of starter tests should someone want to improve efficiency of contains :in-any-order

--- test/midje/checkers/t_collection.clj
+++ test/midje/checkers/t_collection.clj
@@ -5,6 +5,22 @@
         [midje.checkers.chatty :only [chatty-falsehood-to-map
                                       chatty-checker-falsehood?]]))
 (testable-privates midje.checkers.collection separate-looseness)
+
+
+(facts "demonstrating the effects of :in-any-order and ambiguity"
+  ;; In case anyone wants to make the algorithm better.
+  ;; Annoyingly, I seem to have mislaid some more extensive tests. Sloppy.
+  ;; So be extra-careful changing the code - these tests are probably not enough.
+  ["123" "12" "1"] => (contains [#"1" #"2" #"3"] :in-any-order)
+  ["12" "123" "1"] => (contains [#"1" #"2" #"3"] :in-any-order)
+  ["123" "1" "12" ] => (contains [#"1" #"2" #"3"] :in-any-order)
+  ["1" "12" "123"] => (contains [#"1" #"2" #"3"] :in-any-order)
+
+  [0 3 2 'a 1] => (contains #(<= % 3) #(<= % 2) #(<= % 1) :in-any-order :gaps-ok)
+  [0 3 'a 1 2] => (contains #(<= % 3) #(<= % 2) #(<= % 1) :in-any-order :gaps-ok)
+  [0 2 3 'a 1] => (contains #(<= % 3) #(<= % 2) #(<= % 1) :in-any-order :gaps-ok))
+
+

 (fact "left-hand-side: sequentials that are to contain things"
   [3 4 5 700] => (contains [4 5 700])


Refer all symbols from boot-semver

Refer all symbols from boot-semver

--- resources/leiningen/new/lambone/common/build.boot
+++ resources/leiningen/new/lambone/common/build.boot
@@ -69,7 +69,7 @@
          '[clojure.string :as string]
          '[boot.pod :as pod]
          '[boot.util :as util]
-         '[boot-semver.core :refer [get-version]]
+         '[boot-semver.core :refer :all]
          '[pandeiro.boot-http :refer [serve]]
          '[adzerk.env :as env])


Bump boot-reload to avoid an error

Bump boot-reload to avoid an error

--- resources/leiningen/new/lambone/common/build.boot
+++ resources/leiningen/new/lambone/common/build.boot
@@ -50,7 +50,7 @@
                            [adzerk/cljs-console "0.1.1" :exclusions [adzerk/env] :scope "test"]
                            ;; dev only
                            [adzerk/boot-cljs "1.7.228-1" :scope "test"]
-                           [adzerk/boot-reload "0.4.4" :scope "test"]
+                           [adzerk/boot-reload "0.4.8" :scope "test"]
                            [deraen/boot-sass "0.2.1" :scope "test"]
                            [crisptrutski/boot-cljs-test "0.2.2-SNAPSHOT" :scope "test"]
                            [org.slf4j/slf4j-nop "1.7.21" :scope "test"]


minor: change static access style

minor: change static access style

--- reorganize.clj
+++ reorganize.clj
@@ -38,7 +38,7 @@
 (defn create-gui-panel [model]

   (let [pane (JPanel.)
-        box (BoxLayout. pane (. BoxLayout X_AXIS))
+        box (BoxLayout. pane BoxLayout/X_AXIS)
         image1 (create-image "/usr/share/icons/Faenza/apps/32/AdobeReader.png")
         image2 (create-image "/usr/share/icons/Faenza/apps/32/Thunar.png")
         image3 (create-image "/usr/share/icons/Faenza/apps/48/WorldOfGoo.png")


green status wait

green status wait

--- src/es/node.clj
+++ src/es/node.clj
@@ -24,6 +24,7 @@

 (defn build-local-node
   [settings]
+    (info "Building local ES node" settings)
     (.build
       (doto (NodeBuilder/nodeBuilder)
       (.settings (cnv/->settings settings))
@@ -38,8 +39,21 @@
       :node.name "celestial" :cluser.name "celestial-cluster"
       :http.enabled false
       :index.number_of_shards 1
-      :index.number_of_replicas 1
+      :index.number_of_replicas 0
     }))
+
+(defn wait-for-green-health
+  "Wait that the local node is ready see bit.ly/1kRUPet"
+  [indices]
+  (info "Waiting for cluster to be green on" indices)
+  (-> @ES
+      .client
+      .admin
+      .cluster
+      (.prepareHealth (into-array indices))
+      .setWaitForGreenStatus
+      .execute
+      .actionGet))

 (defn start
   "launch en embedded ES node"
@@ -51,11 +65,13 @@
   (es/connect-to-local-node! @ES))

 (defn start-n-connect
-   "Both starts the node and connects to it (only) if not ready"
-   []
+  "Both starts the node and connects to it (only) if not ready"
+  [indices]
   (when-not (and @ES (not (.isClosed @ES)))
     (start)
-    (connect)))
+    (connect)
+    (wait-for-green-health indices)
+    ))

 (defn stop
   "stops embedded ES node"


Adds exception handling to scan-tasks and launch-tasks (#1470)

--- scheduler/src/cook/kubernetes/compute_cluster.clj
+++ scheduler/src/cook/kubernetes/compute_cluster.clj
@@ -94,14 +94,19 @@
 (defn scan-tasks
   "Scan all taskids. Note: May block or be slow due to rate limits."
   [{:keys [name] :as kcc}]
-  (log/info "In compute cluster" name ", starting taskid scan")
+  (log/info "In" name "compute cluster, starting taskid scan")
   ; TODO Add in rate limits; only visit non-running/running task so fast.
   ; TODO Add in maximum-visit frequency. Only visit a task once every XX seconds.
   (let [taskids (taskids-to-scan kcc)]
-    (log/info "In compute cluster" name ", doing taskid scan. Visiting" (count taskids) "taskids")
+    (log/info "In" name "compute cluster, doing taskid scan. Visiting" (count taskids) "taskids")
     (doseq [^String taskid taskids]
-      (log/info "In compute cluster" name ", doing scan of " taskid)
-      (controller/scan-process kcc taskid))))
+      (try
+        (log/info "In" name "compute cluster, doing scan of" taskid)
+        (controller/scan-process kcc taskid)
+        (catch Exception e
+          (log/error e "In" name
+                     "compute cluster, encountered exception scanning task"
+                     taskid))))))

 (defn regular-scanner
   "Trigger a channel that scans all taskids (shortly) after this function is invoked and on a regular interval."
@@ -207,7 +212,7 @@
                                      pool->fenzo-atom namespace-config scan-frequency-seconds-config max-pods-per-node
                                      synthetic-pods-config node-blocklist-labels]
   cc/ComputeCluster
-  (launch-tasks [this offers task-metadata-seq]
+  (launch-tasks [this _ task-metadata-seq]
     (doseq [task-metadata task-metadata-seq]
       ; Has the workload of launching tasks changed or has the cost of doing them changed?
       ; Note we can't use timer/time! because it wraps the body in a Callable, which rebinds 'this' to another 'this'
@@ -215,13 +220,19 @@
       ; In addition, it captures controller/update-cook-expected-state and prevents with-redefs on
       ; update-cook-expected-state from working correctly in unit tests.
       (let [timer-context (timers/start (metrics/timer "compute-cluster-launch-tasks" name))
-            pod-namespace (get-namespace-from-task-metadata namespace-config task-metadata)]
-        (controller/update-cook-expected-state
-          this
-          (:task-id task-metadata)
-          {:cook-expected-state :cook-expected-state/starting
-           :launch-pod {:pod (api/task-metadata->pod pod-namespace name task-metadata)}})
-        (.stop timer-context))))
+            pod-namespace (get-namespace-from-task-metadata namespace-config task-metadata)
+            pod-name (:task-id task-metadata)
+            ^V1Pod pod (api/task-metadata->pod pod-namespace name task-metadata)
+            new-cook-expected-state-dict {:cook-expected-state :cook-expected-state/starting
+                                          :launch-pod {:pod pod}}]
+        (try
+          (controller/update-cook-expected-state this pod-name new-cook-expected-state-dict)
+          (.stop timer-context)
+          (catch Exception e
+            (log/error e "In" name "compute cluster, encountered exception launching task"
+                       {:pod-name pod-name
+                        :pod-namespace pod-namespace
+                        :task-metadata task-metadata}))))))

   (kill-task [this task-id]
     ; Note we can't use timer/time! because it wraps the body in a Callable, which rebinds 'this' to another 'this'


Add basic menu rendering for groups of shapes.

--- src/uxbox/ui/workspace/options.cljs
+++ src/uxbox/ui/workspace/options.cljs
@@ -12,6 +12,7 @@

 (def +menus-map+
   {:builtin/icon [:menu/measures :menu/fill]
+   :builtin/group [:menu/measures]
    :builtin/icon-svg [:menu/measures]})

 (def +menus-by-id+


Override default connection-ttl from 1 minute to 30 minutes [IMMUTANT-295]

--- support/build-support/src/main/clojure/immutant/build/tools.clj
+++ support/build-support/src/main/clojure/immutant/build/tools.clj
@@ -276,10 +276,14 @@
       disable-hq-security
       enable-hq-jmx))

-(defn disable-flow-control
-  "Assumes loc is :jms-connection-factories and its first child is the in-vm one"
+(defn update-hq-invmcf
+  "Assumes loc is :connection-factory"
   [loc]
-  (zip/append-child (zip/down loc) {:tag :consumer-window-size :content ["1"]}))
+  (if (= "InVmConnectionFactory" (-> loc zip/node :attrs :name))
+    (-> loc
+        (zip/append-child {:tag :consumer-window-size :content ["1"]})
+        (zip/append-child {:tag :connection-ttl :content ["1800000"]}))
+    loc))

 (defn append-system-properties [loc]
   (if (looking-at? :system-properties (zip/right loc))
@@ -367,7 +371,7 @@
                 :max-size-bytes                 (zip/edit loc assoc :content ["20971520"])
                 :address-full-policy            (zip/edit loc assoc :content ["PAGE"])
                 :hornetq-server                 (update-hq-server loc)
-                :jms-connection-factories       (disable-flow-control loc)
+                :connection-factory             (update-hq-invmcf loc)
                 :servers                        (replace-servers loc)
                 :server-groups                  (replace-server-groups loc)
                 :socket-binding-group           (fix-socket-binding-group loc)


adding the footer to the layout view

adding the footer to the layout view

--- src-cljs/bitfondue/core.cljs
+++ src-cljs/bitfondue/core.cljs
@@ -67,7 +67,9 @@
   [:div
    [header]
    [:br]
-   [:div.container content]])
+   [:div.container content]
+   [:br]
+   [footer]])

 (defn home-anonymous []
   [layout [:h1 "Home"]])


Remove unnecessary WebViewClient

Remove unnecessary WebViewClient

--- src-droid/clojure/com/sparrho/supperdemo/main.clj
+++ src-droid/clojure/com/sparrho/supperdemo/main.clj
@@ -2,19 +2,9 @@
   (:require [neko.activity :refer [defactivity set-content-view!]]
             [neko.find-view :refer [find-view]]
             [neko.threading :refer [on-ui]]
-            [com.sparrho.supperdemo.jsinterface])
-  (:import [android.webkit WebViewClient]))
+            [com.sparrho.supperdemo.jsinterface]))

-;Based on https://github.com/sattvik/Clojure-Android-Examples/
-(defn make-webview-client
-  "Constructs an instance of WebViewClient that allows us to manage the
-  WebView."
-  [web-view]
-  (proxy [WebViewClient] []
-    (shouldOverrideUrlLoading [view url]
-                              (.loadUrl view url)
-                              true)))
-
+;TODO: Type hinting!
 (defactivity com.sparrho.supperdemo.InitActivity
   :key :main
   :on-create
@@ -32,6 +22,5 @@
          (.setJavaScriptEnabled true))
        (doto web-view
          (.addJavascriptInterface (com.sparrho.supperdemo.jsinterface.interop. this) "Android")
-         (.loadUrl "file:///android_asset/index.html")
-         (.setWebViewClient (make-webview-client web-view)))
+         (.loadUrl "file:///android_asset/index.html"))
        ))))


todomvc: fix min build by including carry-atom-sync source path

--- examples/todomvc/project.clj
+++ examples/todomvc/project.clj
@@ -75,7 +75,8 @@
                                        "../../contrib/persistence/src"
                                        "../../contrib/logging/src"
                                        "../../contrib/debugger/src"
-                                       "../../contrib/schema/src"]
+                                       "../../contrib/schema/src"
+                                       "../../contrib/atom-sync/src"]
                         :compiler     {:main           app.core
                                        :output-to      "resources/public/js/compiled/frontend.js"
                                        :optimizations  :advanced


update example

update example

--- examples/uberjar/project.clj
+++ examples/uberjar/project.clj
@@ -3,5 +3,4 @@
   :dependencies [[clojure "1.2.0"]
                  [clojure-contrib "1.2.0"]
                  [clojure-csv/clojure-csv "1.1.0"]]
-  :omit-source true
   :main uberjar)


Download shapefile for CSV lookups.

Download shapefile for CSV lookups.

--- src/clj/popchange/lib/raster_calculation_ajax.clj
+++ src/clj/popchange/lib/raster_calculation_ajax.clj
@@ -126,6 +126,8 @@

 (def source-data-url (partial str (:source-data-host config) "/"))

+(def source-data-csv-shapefile (source-data-url "vector-grid.zip")) ;; File in data
+
 (defn source-data-links
   [{:keys [asc csv csvt counts-table title] :as params}]
   (if (some #(if % true) (-> params (dissoc :counts-table) vals))
@@ -159,4 +161,8 @@
     [:a {:href (:img-src-tab params) :target "_blank"} "Download MapInfo TAB"]
     [:br] [:br]
     (source-data-links (-> params :source-data :set1))
-    (source-data-links (-> params :source-data :set2))]])
+    (source-data-links (-> params :source-data :set2))
+    (if (or (-> params :source-data :set1 :csv) (-> params :source-data :set2 :csv))
+      [:div
+       [:br]
+       [:a {:href source-data-csv-shapefile :target "_blank"} "Shapefile for CSV lookup"]])]])


Update frontend dependencies.

Update frontend dependencies.

--- frontend/project.clj
+++ frontend/project.clj
@@ -24,11 +24,11 @@
                  [cljsjs/react-dom "15.4.2-2"]
                  [cljsjs/react-dom-server "15.4.2-2"]

-                 [funcool/beicon "3.1.1"]
+                 [funcool/beicon "3.2.0"]
                  [funcool/bide "1.4.0"]
                  [funcool/cuerdas "2.0.3"]
                  [funcool/lentes "1.2.0"]
-                 [funcool/potok "2.0.0"]]
+                 [funcool/potok "2.1.0"]]
   :plugins [[lein-ancient "0.6.10"]]
   :clean-targets ^{:protect false} ["resources/public/js" "target"]
   )


Update beicon to 2.9.0.

Update beicon to 2.9.0.

--- frontend/project.clj
+++ frontend/project.clj
@@ -25,7 +25,7 @@
                  [funcool/potok "1.2.0"]
                  [funcool/struct "1.0.0"]
                  [funcool/lentes "1.2.0"]
-                 [funcool/beicon "2.8.0"]
+                 [funcool/beicon "2.9.0"]
                  [funcool/cuerdas "2.0.2"]
                  [funcool/bide "1.4.0"]]
   :plugins [[lein-ancient "0.6.10"]]


set up dominant-component

set up dominant-component

--- frontend/components/app.cljs
+++ frontend/components/app.cljs
@@ -8,6 +8,7 @@
             [frontend.components.key-queue :as keyq]
             [frontend.components.navbar :as navbar]
             [frontend.components.placeholder :as placeholder]
+            [frontend.components.common :as common]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]
             [sablono.core :as html :refer-macros [html]]))
@@ -15,10 +16,17 @@
 (def keymap
   (atom nil))

+(defn loading [app owner opts]
+  (reify
+    om/IRender
+    (render [_] (html [:div.loading-spinner common/spinner]))))
+
 (defn dominant-component [app-state]
-  (if (get-in app-state [:inspected-project :build-num])
-    build-com/build
-    dashboard/dashboard))
+  (condp = (get-in app-state [:navigation-point])
+    :build build-com/build
+    :dashboard dashboard/dashboard
+    :add-projects add-projects/add-projects
+    :loading loading))

 (defn app [app owner opts]
   (reify
@@ -38,6 +46,6 @@
           [:header
            (om/build navbar/navbar app {:opts opts})]
           [:main
-           (om/build add-projects/add-projects app {:opts opts})]
+           (om/build dom-com app {:opts opts})]
           [:footer
            (footer/footer)]])))))


removed side bar in favour of vertical menu

--- cljx/plongeur-cljs/src/plongeur/view.cljs
+++ cljx/plongeur-cljs/src/plongeur/view.cljs
@@ -1,4 +1,5 @@
 (ns plongeur.view
+  "See https://github.com/CreativeIT/material-dashboard-lite"
   (:require [cljs.core.async :as a :refer [<! >! timeout tap chan pipe close!]]
             [quiescent.core :as q :include-macros true :refer-macros [defcomponent]]
             [sablono.core :refer-macros [html]]
@@ -11,15 +12,6 @@
             [plongeur.model :as m]
             [plongeur.sigma :as s])
   (:require-macros [cljs.core.async.macros :refer [go go-loop]]))
-
-#_(defn rand-node [_]
-  (let [node-id (str (rand-int 50))]
-    {:id    node-id
-     :label node-id
-     :x (rand-int 20)
-     :y (rand-int 20)
-     :size (-> (rand-int 10) (* 0.1))
-     :color "#FF9"}))

 ;; MDL machinery

@@ -47,8 +39,6 @@
                       active-state     (.activeState sigma-plugins sigma-instance)

                       ;drag-listener    (.dragNodes   sigma-plugins sigma-instance sigma-renderer active-state)
-
-                      _ (.log js/console active-state)

                       web-response-tap (->> (chan 10)
                                             (tap web-response-mult))]
@@ -97,20 +87,40 @@

            id

-           [:div {}
-
-            [:div {:on-click   #(go (>! drop-plot id))
-                   :class-name "mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored mdl-js-ripple-effect"}
-             [:i {:class-name "material-icons"} "delete"]]
-
-            [:div {:on-click   #(go (>! drop-plot id))
-                   :class-name "mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored mdl-js-ripple-effect"}
-             [:i {:class-name "material-icons"} "delete"]]]
+           [:div {:on-click   #(go (>! drop-plot id))
+                  :class-name "mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab"}
+            [:i {:class-name "material-icons"} "delete"]]

            ]]]))

+(defcomponent Menu
+  [state {:keys [debug]}]
+  (html [:ul {:class-name "mdl-menu mdl-list mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect mdl-shadow--2dp account-dropdown"
+              :for "more-vert-btn"}
+
+         [:li {:class-name "mdl-menu__item mdl-list__item"}
+          [:span {:class-name "mdl-list__item-primary-content"}
+           [:i {:class-name "material-icons mdl-list__item-icon"} "settings"] "Configuration"]]
+
+         [:li {:class-name "list__item--border-top"}]
+
+         [:li {:class-name "mdl-menu__item mdl-list__item"}
+          [:span {:on-click #(go (>! debug :click))
+                  :class-name "mdl-list__item-primary-content"}
+           [:i {:class-name "material-icons mdl-list__item-icon"} "get_app"] "Write app state to console"]]
+
+         [:li {:class-name "list__item--border-top"}]
+
+         [:li {:class-name "mdl-menu__item mdl-list__item"}
+          [:span {:class-name "mdl-list__item-primary-content"}
+           [:i {:class-name "material-icons mdl-list__item-icon"} "attach_file"] "Publication"]]
+
+         [:li {:class-name "mdl-menu__item mdl-list__item"}
+          [:span {:class-name "mdl-list__item-primary-content"}
+           [:i {:class-name "material-icons mdl-list__item-icon"} "link"] "Github"]]]))
+
 (defcomponent Header
-  [state {:keys [debug add-plot web-response-chan] :as cmd-chans}]
+  [state {:keys [add-plot web-response-chan] :as cmd-chans}]
   (html [:header {:class-name "mdl-layout__header"}
          [:div {:class-name "mdl-layout__header-row"}

@@ -119,40 +129,15 @@
           [:div {:on-click   #(go (>! add-plot :tda))
                  :hidden     (>= (m/plot-count state) 4)
                  :class-name "material-icons mdl-badge mdl-button--icon"} "add"]
+
           [:div {:on-click #(go (>! web-response-chan :click))
                  :class-name "material-icons mdl-badge mdl-button--icon"} "refresh"]
-          [:div {:on-click #(go (>! debug :click))
-                 :class-name "material-icons mdl-badge mdl-button--icon"} "print"]

-          ]]))
+          [:button {:id "more-vert-btn"
+                    :class-name "mdl-button mdl-js-button mdl-button--icon"}
+           [:i {:class-name "material-icons"} "more_vert"]]

-(defcomponent Drawer
-  [state cmd-chans]
-  (html [:div {:class-name "mdl-layout__drawer"}
-         [:header {} "(0_0)"]
-         [:nav {:class-name "mdl-navigation"}
-          [:a {:class-name "mdl-navigation__link mdl-navigation__link--current"
-               :href "index.html"}
-           [:i {:class-name "material-icons"
-                :role       "presentation"} "dashboard"] "Dashboard"]
-          [:a {:class-name "mdl-navigation__link"
-               :href "config.html"}
-           [:i {:class-name "material-icons"
-                :role       "presentation"} "settings"] "Settings"]
-          [:a {:class-name "mdl-navigation__link"
-               :href "config.html"}
-           [:i {:class-name "material-icons"
-                :role       "presentation"} "reorder"] "Logs"]
-
-          [:div {:class-name "mdl-layout-spacer"}]
-
-          [:a {:class-name "mdl-navigation__link"
-               :href "https://github.com/tmoerman/plongeur"
-               :target "_blank"}
-           [:i {:class-name "material-icons"
-                :role       "presentation"} "link"] "Github"]
-
-          ]]))
+          (Menu state cmd-chans)]]))

 (defcomponent Grid
   [state cmd-chans]
@@ -166,9 +151,9 @@
   [state cmd-chans]
   (html [:div {:id "plongeur-main"}
          [:div {:id         "layout"
-                :class-name "mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header is-small-screen"}
+                :class-name "mdl-layout mdl-js-layout mdl-layout--fixed-header"}
           (Header state cmd-chans)
-          (Drawer state cmd-chans)
+          #_(Drawer state cmd-chans)
           (Grid   state cmd-chans)]]))

 (defn view


azulenoids.clj: function chain-end uses the loop construct

--- clojure/org/gavrog/clojure/azulenoids.clj
+++ clojure/org/gavrog/clojure/azulenoids.clj
@@ -21,14 +21,13 @@
   (reduce #(.op ds %2 %1) D idxs))

 (defn chain-end [ds D i j]
-  (letfn [(step [E]
-                (let [E* (walk ds E j)]
-                  (cond
-                    (nil? E*) E
-                    (= E E*) E
-                    (= D E*) nil
-                    :else (recur (walk ds E j i)))))]
-    (step (walk ds D i))))
+  (loop [E (walk ds D i)]
+    (let [E* (walk ds E j)]
+      (cond
+        (nil? E*) E
+        (= E E*) E
+        (= D E*) nil
+        :else (recur (walk ds E j i))))))

 (defn boundary-chambers [ds D i j k]
   (iterate-cycle [#(walk ds %1 i) #(chain-end ds %1 j k)] D))


workin sort-table

workin sort-table

--- src/hackerrank/security/keyword_transposition.clj
+++ src/hackerrank/security/keyword_transposition.clj
@@ -56,7 +56,7 @@

 (defn sort-table [transposed string]
   (let [s (join (sort (distinct-string string)))]
-    (map #(find-first-starts-with table %) s)))
+    (map #(find-first-starts-with transposed (str %)) s)))

 (defn keyword-transposition

@@ -85,7 +85,7 @@
 ;; (str/join (set/difference (set (seq "abcdsport")) (set (seq "sport"))))

 ;;;; transpose-table
-(def table ["safku" "pbglv" "ochmw" "rdinx" "tejqy"])
+;; (def table ["safku" "pbglv" "ochmw" "rdinx" "tejqy"])
 ;; (def a (map first table))
 ;; (def b (map second table))
 ;; (def c (map #(nth % 2) table))
@@ -103,7 +103,7 @@
 ;; (map #(transpose-row table %) (range (count (first table))))

-(def s (join (sort "sport")))
+;; (def s (join (sort "sport")))

-(map identity s)
-(first (filter #(str/starts-with? % "o") table))
+;; (map identity s)
+;; (first (filter #(str/starts-with? % "o") table))


+(defn reset): reload all the things

+(defn reset): reload all the things

--- src/babel/espanol/writer.clj
+++ src/babel/espanol/writer.clj
@@ -29,6 +29,10 @@

 (defn fo [expression]
   (morph/fo expression))
+
+(defn reset []
+  (refresh-all)
+  (rlog4j!))

 (defn todos [ & [count]]
   (let [count (if count (Integer. count) 10)


make the parse-json-line-items private since it won't be used outside the migrations namespace

--- src/bitfondue/migrations.clj
+++ src/bitfondue/migrations.clj
@@ -24,7 +24,7 @@

 ;; Migrate the existing data into the new database
-(defn parse-json-line-items
+(defn ^:private parse-json-line-items
   "Parses the current .json line item file into a collection of maps"
   [file-name]
   (with-open [rdr (clojure.java.io/reader file-name)]


Added some functions.

Added some functions.

--- src/main/cljc/clojure_club/rpg_spec/mbastian.cljc
+++ src/main/cljc/clojure_club/rpg_spec/mbastian.cljc
@@ -47,26 +47,34 @@

 (s/def ::skills (s/with-gen (s/* ::skill)
                             #(gen/fmap
-                               (fn [d] (take 2 d))
+                               (fn [d] (set (take 2 d)))
                                (s/gen (s/+ ::skill)))))

 (s/def ::weapon-class #{:ranged :meelee})

+(s/def ::level (s/and int? pos?))
+
 (s/def ::character
-  (s/keys :req [::name ::race ::character-class ::character-stats ::skills ::weapon-class]))
+  (s/keys :req [::name ::race ::level ::character-class ::character-stats ::skills ::weapon-class]))

 (gen/sample (s/gen ::character) 10)

-(defn save [c attr]
-  {:pre [(s/assert ::character c)]}
-  (get-in c [::character-stats attr]))
+;;;;;;;;;;;;;;;Using pre/post conds;;;;;;;;;;;;;;
+;Conditions only work when asserts are enabled
+(s/check-asserts true)

-(save (first (gen/sample (s/gen ::character) 10)) ::str)
+(defn level-up [c]
+  {:pre [(s/assert ::character c)]
+   :post [(and (s/assert ::character %) (> (::level %) (::level c)))]}
+  (update c ::level inc))

-(save
+(level-up (first (gen/sample (s/gen ::character) 10)))
+
+(level-up
   {:name "",
    :race :clojure-club.rpg-spec.mbastian/elf,
    :character-class :clojure-club.rpg-spec.mbastian/ranger,
+   :level 2
    :character-stats {:str 6,
                      :dex 4,
                      :con 4,
@@ -74,7 +82,19 @@
                      :wis 4,
                      :cha 5},
    :skills #{:survival},
-   :weapon-class :meelee}
-  ::str)
+   :weapon-class :meelee})

-(save 3 4)+(level-up 3)
+
+;;;;;;;;;;;;;;;Using instrument;;;;;;;;;;;;;;
+(defn enskill [c]
+  (update c ::skills conj :stealth))
+
+(s/fdef enskill
+        :args (s/cat :character ::character)
+        :ret ::character)
+
+(stest/instrument `enskill)
+
+(enskill (first (gen/sample (s/gen ::character) 10)))
+(enskill 34)


Use a transient vector when combining render results

--- src/main/clojure/cascade/internal/viewbuilder.clj
+++ src/main/clojure/cascade/internal/viewbuilder.clj
@@ -16,8 +16,6 @@
   (:use (clojure.contrib monads [pprint :only (pprint)])
         (cascade dom fail)
         (cascade.internal utils parser)))
-
-; TODO: Turn this into a multimethod to make it more extensible.

 (defn convert-render-result
   [any]
@@ -38,14 +36,14 @@
 or a collection of DOM nodes (or a nested collection of DOM nodes, etc.). Strings are also allowed,
 which are converted into :text DOM nodes."
   [& render-results]
-  (loop [output []
+  (loop [output (transient [])
          queue render-results]
     (let [current (first queue)
           remainder (next queue)]
       (cond
-        (nil? current) (if (empty? remainder) output (recur output remainder))
+        (nil? current) (if (empty? remainder) (persistent! output) (recur output remainder))
         (sequential? current) (recur output (concat current remainder))
-        :otherwise (recur (conj output (convert-render-result current)) remainder)))))
+        :otherwise (recur (conj! output (convert-render-result current)) remainder)))))

 (with-monad parser-m
   (declare parse-embedded-template)


adds logging if we detect that with-correlation-id binding executed on different threads (#438)

--- waiter/src/waiter/correlation_id.clj
+++ waiter/src/waiter/correlation_id.clj
@@ -45,7 +45,14 @@
   "Executes the body with the specified value of correlation-id."
   [correlation-id & body]
   `(binding [dynamic-correlation-id ~correlation-id]
-     ~@body))
+     (let [start-thread-id# (.getId (Thread/currentThread))
+           result# (do ~@body)
+           end-thread-id# (.getId (Thread/currentThread))]
+       (when (not= start-thread-id# end-thread-id#)
+         (log/warn "with-correlation-id binding executed on different threads"
+                   {:correlation-id ~correlation-id
+                    :thread-ids {:end end-thread-id# :start start-thread-id#}}))
+       result#)))

 (defn get-correlation-id
   "Retrieve the value of the current correlation-id."


add terminal-val

add terminal-val

--- src/clj/com/rpl/specter.cljx
+++ src/clj/com/rpl/specter.cljx
@@ -9,6 +9,7 @@
                defnav
                defpathedfn
                richnav
+               defnavconstructor
               ]]
             [com.rpl.specter.util-macros :refer
               [doseqres]]
@@ -21,7 +22,8 @@
              defcollector
              defnav
              defpathedfn
-             richnav]]
+             richnav
+             defnavconstructor]]
     #+clj [com.rpl.specter.util-macros :only [doseqres]]
     )
   (:require [com.rpl.specter.impl :as i]
@@ -218,6 +220,13 @@
     (transform* [params params-idx vals structure next-fn]
       (i/terminal* params params-idx vals structure)
       )))
+
+(defnavconstructor terminal-val
+  "Like `terminal` but specifies a val to set at the location regardless of
+   the collected values or the value at the location."
+  [p terminal]
+  [v]
+  (p (constantly v)))

 (def
   ^{:doc "Navigate to every element of the collection. For maps navigates to


#hh/var tag reader added to config ns to parse edn config files

--- src/clj/hellhound/config.clj
+++ src/clj/hellhound/config.clj
@@ -10,6 +10,7 @@

 (def ^{:doc "Default configuration hash-map of the hellhound application.
 check out key values of `:keys-doc` meta key."}
+
   ^{:keys-doc1
     {:http-host "The default hostname or ip address to be use as
                     webserver address (default: localhost)"
@@ -24,6 +25,21 @@
    :http-port         3000
    :public-files-path "public"})

+(defn var-reader
+  "Reader function for `#hh/var` edn tag which resolve the given
+  string as a var and returns the value related to that var."
+  [value]
+  (let [[namespace var-symbol] (map #(symbol %)
+                                    (clojure.string/split value #"/"))]
+    (delay
+     (let [resolved-symbol (ns-resolve namespace var-symbol)]
+       (if-not (nil? resolved-symbol)
+         @resolved-symbol
+         nil)))))
+
+(def readers
+  {'hh/var var-reader})
+
 (defn read-config
   "Read the content of the config file with the given `config-name`
   and return a clojure data structure."
@@ -31,6 +47,5 @@
   (let [resource (io/resource config-name)]
     (if (nil? resource)
       (throw (ex-info
-              (format "Can't find the '%s' config file" config-name)
-              {})))
-    (edn/read-string (slurp resource))))
+              (format "Can't find the '%s' config file" config-name) {})))
+    (edn/read-string {:readers readers} (slurp resource))))


WIP refine pagination for sets with many pages

--- src/clj_money/pagination.clj
+++ src/clj_money/pagination.clj
@@ -1,5 +1,7 @@
 (ns clj-money.pagination
   (:require [clojure.spec :as s]
+            [clojure.pprint :refer [pprint]]
+            [clojure.set :refer [rename-keys]]
             [clj-money.url :as url]
             [clj-money.coercion :as coercion]))

@@ -7,44 +9,69 @@
 (s/def ::per-page integer?)
 (s/def ::total integer?)
 (s/def ::url map?)
+(s/def ::max-pages (s/and integer? #(< 3)))
 (s/def ::pagination-options (s/keys :req-un [::total ::url] :opt-un [::page ::per-page]))

 (def ^:private menu-coercion-rules
-  (coercion/rules :integer [:page] [:per-page] [:total]))
+  (coercion/rules :integer [:page] [:per-page] [:total] [:max-pages]))

-(defn- nav-item
+(defn- validate-options
+  [options]
+  (let [coerced (coercion/coerce menu-coercion-rules options)]
+    (if (s/valid? ::pagination-options coerced)
+      (merge {:page 0 :per-page 10 :max-pages 10} coerced)
+      (throw (RuntimeException. (str "Invalid pagination options: "
+                                     (s/explain-data ::pagination-options coerced)))))))
+
+(defmulti ^:private nav-item
   "Renders a single navigation item"
-  [page current-page per-page url]
+  (fn [options]
+    (if (vector? (:page options))
+      :placeholder
+      :regular)))
+
+(defmethod ^:private nav-item :regular
+  [{:keys [page current-page per-page url] :as options}]
   [:li {:class (when (= page current-page) "active")}
    [:a {:href (-> url
                   (url/query {:page page :per-page per-page})
                   url/format-url)}
     (str (+ 1 page))]])

-(defn- validate-options
-  [options]
-  (let [coerced (coercion/coerce menu-coercion-rules options)]
-    (if (s/valid? ::pagination-options coerced)
-      (merge {:page 0 :per-page 10} coerced)
-      (throw (RuntimeException. (str "Invalid pagination options: "
-                                     (s/explain-data ::pagination-options coerced)))))))
+(defmethod ^:private nav-item :placeholder
+  [{:keys [page current-page per-page url]}]
+  [:li
+   [:a {:href "#"}
+    "..."]])

 (defn nav
   "Renders pagination navigation for the specified options

-  :page     - the current page index
-  :per-page - the number of entries per page
-  :total    - the total number of items to be paginated
-  :url      - the base url for the navigation links"
+  :page      - the current page index
+  :per-page  - the number of entries per page
+  :total     - the total number of items to be paginated
+  :max-pages - the maximum number of pages explicitly listed
+  :url       - the base url for the navigation links"
   [options]
   [:nav {:aria-label "Page navigation"}
    [:ul.pagination
-    (let [{:keys [url
-                  page
-                  per-page
-                  total]} (validate-options options)
-          page-count (Math/ceil (/ total per-page))]
-      (map #(nav-item % page per-page url) (range page-count)))]])
+    (let [{:keys [total per-page max-pages]
+           :as validated-options} (-> options
+                                      validate-options
+                                      (rename-keys {:page :current-page}))
+          page-count (int (Math/ceil (/ total per-page)))
+          pages (loop [page 0 result []]
+                  (if (<= page-count page)
+                    result
+                    (recur (if (< max-pages page)
+                             page-count
+                             (+ page 1))
+                           (conj result
+                                 (assoc validated-options
+                                        :page (if (< max-pages page)
+                                                (- page-count 1)
+                                                page))))))]
+      (map #(nav-item %) pages))]])

 (defn prepare-options
   "Accepts a map of parameters (as from a web request) and returns


remove comment to test heroku

remove comment to test heroku

--- src/cljs/dodgeball/core.cljs
+++ src/cljs/dodgeball/core.cljs
@@ -193,7 +193,7 @@
   (go
    (loop []
      (let [event (<! action-queue)]
-       (println event)
+       ;(println event)
        (case (:type event)
          :select-unit   (select-unit app owner (:coords event))
          :deselect-unit (deselect-unit owner)


Ideas added only to focused district. Scoped unique titles.

--- src/cljs/geoforms/forms.cljs
+++ src/cljs/geoforms/forms.cljs
@@ -61,7 +61,7 @@

     (when-let [title (:title idea)]
       (and (seq title)
-           (some (comp #{title} :title) @db/ideas)))
+           (some (comp #{title} :title) (district-ideas @db/selected-district))))
     (assoc :title (str (snippet :title) " " (snippet :already-used)))

     (empty? (:category idea))
@@ -78,7 +78,6 @@
   "Update errors atom, and return true if there were any errors."
   [doc]
   (let [errors (validate-idea @doc)]
-    (prn errors)
     (swap! doc assoc :errors errors)
     (empty? errors)))

@@ -90,8 +89,7 @@
 (defn normalize-idea [idea]
   (-> idea
       (update :urls #(into [] (vals (apply sorted-set %))))
-      ;; just add to all districts for now
-      (assoc :districts (selected-districts))))
+      (assoc :districts [@db/selected-district])))

 (defn submit-idea!
   [doc]


Building toolbar's event handler

Building toolbar's event handler

--- src/cljs/mathom/toolbar.cljs
+++ src/cljs/mathom/toolbar.cljs
@@ -8,16 +8,6 @@
   (let [prev (.getElementById js/document "mathom_toolbar")]
     (if (not (nil? prev))
       (.remove prev))))
-
-(defn setup
-  []
-  (let [body (aget (.getElementsByTagName js/document "body") 0)
-        tb (.createElement js/document "div")]
-    (clean)
-    (.setAttribute tb "id" "mathom_toolbar")
-    (.appendChild body tb)
-    (swap! tool #(assoc @tool :bar tb)) ; To get access to generated node
-    ))

 (defn set-content
   [content]
@@ -31,6 +21,19 @@

")

+(defn setup
+  []
+  (let [body (aget (.getElementsByTagName js/document "body") 0)
+        tb (.createElement js/document "div")]
+    (clean)
+    (.setAttribute tb "id" "mathom_toolbar")
+    (.appendChild body tb)
+    (set-content content)
+    (swap! tool #(assoc @tool :bar tb)) ; To get access to generated node
+    ))
+
 (defn attach-listener
-  []
-  (.addEventListener (:bar @tool) "click" #(println "que" (aget (.-target %) "id"))))
+  [cbdb]
+  (.addEventListener (:bar @tool)
+                     "click"
+                     #((get cbdb (aget (.-target %) "id")))))


Fix let no splash screen when restart game.

--- src/cljs/reversi/phaser.cljs
+++ src/cljs/reversi/phaser.cljs
@@ -229,10 +229,10 @@
     (doseq [pair *assets-table*]
       (let [name (first pair)
             path (second pair)]
-        (.image loader name path)))))
+        (.image loader name path)))
+    (set! (.-backgroundColor (.-stage game)) "#ffffff")))

 (defn create [game]
-  (set! (.-backgroundColor (.-stage game)) "#ffffff")
   (.tileSprite (.-add game) 0 0
                *phaser-border-width*
                *phaser-border-height* "border")


#30 prettier PR diff

#30 prettier PR diff

--- src/org/zalando/stups/friboo/system/audit_log.clj
+++ src/org/zalando/stups/friboo/system/audit_log.clj
@@ -30,7 +30,6 @@
              (fn [stream jsonGenerator]
                (.writeString jsonGenerator
                              (str "Some " (.getName (class stream)) ". Content omitted."))))
-

 (defn running? [component]
   (:audit-logs component))


Polishing output

Polishing output

--- src/cyanite_remover/core.clj
+++ src/cyanite_remover/core.clj
@@ -582,10 +582,13 @@
         (if (t-path-leaf? tree-impl path)
           (when-not @clog/print-log?
             (prog/tick-by (t-get tree-impl path)))
-          (do
+          (let [spath (path-list2str path)]
+            (if (seq path)
+              (clog/info (str "Checking path: " spath)))
             (when (t-path-empty? tree-impl path)
+              (log/debug (str "Path '" spath "' is empty"))
               (t-delete-path tree-impl path)
-              (swap! removed-paths conj (path-list2str path)))
+              (swap! removed-paths conj spath))
             (when (and (not @clog/print-log?) (seq path))
               (prog/tick)))))
       (tp-get-data [this]


Hint added to the first problem

Hint added to the first problem

--- src/foreclojure/data_set.clj
+++ src/foreclojure/data_set.clj
@@ -8,7 +8,7 @@
              {:_id 1
               :title "Nothing but the Truth"
               :times-solved 0
-              :description "This is a clojure form.  Enter a value which will make the form evaluate to true.  Don't over think it!  If you are confused, see the getting started page."
+              :description "This is a clojure form.  Enter a value which will make the form evaluate to true.  Don't over think it!  If you are confused, see the getting started page.  Hint: true is equal to true."
               :tags ["elementary"]
               :tests ["(= __ true)"]})


Problem added - "Filter Perfect Squares"

--- src/foreclojure/data_set.clj
+++ src/foreclojure/data_set.clj
@@ -765,9 +765,19 @@
 		   "(= :x (__ [[:x :e :e]\n           [:o :x :e]\n           [:o :e :x]]))"
 		   "(= :o (__ [[:x :e :o]\n           [:x :o :e]\n           [:o :e :x]]))"
 		   "(= nil (__ [[:x :o :x]\n            [:x :o :x]\n            [:o :x :o]]))"]})
-
-      (insert! :problems
-           {:_id 74
+
+ (insert! :problems
+          {:_id 74
+           :title "Filter Perfect Squares"
+           :times-solved 0
+           :description "Given a string of comma separated integers, write a function which returns a new comma separated string that only contains the numbers which are perfect squares."
+           :tags ["medium"]
+           :tests ["(= (__ \"4,5,6,7,8,9\") \"4,9\")"
+		   "(= (__ \"15,16,25,36,37\") \"16,25,36\")"]})
+
+
+      (insert! :problems
+           {:_id 75
             :title "Power Set"
             :times-solved 0
             :description "A power set is the set of all subsets of a given set. Given a list, produce a set of sublists while preserving the order of elements."


Fix bad merge in problems.clj

Fix bad merge in problems.clj

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -2,7 +2,7 @@
   (:use (foreclojure utils
                      [social :only [tweet-link gist!]]
                      [feeds :only [create-feed]]
-                     [foreclojure.config :only [advanced-user-count]]
+                     [config :only [advanced-user-count]]
                      [users :only [golfer?]])
         [clojail core testers]
         somnium.congomongo


Use $set to avoid stomping over other preexisting properties

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -488,16 +488,15 @@

         (update! :problems
                  {:_id id}
-                 {:_id id
-                  :title title
-                  :difficulty difficulty
-                  :times-solved (or (:times-solved existing-problem) 0)
-                  :description description
-                  :tags (re-seq #"\S+" tags)
-                  :restricted (re-seq #"\S+" restricted)
-                  :tests (s/split code #"\r\n\r\n")
-                  :user (if (empty? author) user author)
-                  :approved approved})
+                 {:$set
+                  {:title title
+                   :difficulty difficulty
+                   :description description
+                   :tags (re-seq #"\S+" tags)
+                   :restricted (re-seq #"\S+" restricted)
+                   :tests (s/split code #"\r\n\r\n")
+                   :user (if (empty? author) user author)
+                   :approved approved}})
         (flash-msg "Thank you for submitting a problem! Be sure to check back to see it posted." "/problems"))
       (flash-error "You are not authorized to submit a problem." "/problems"))))


Remove bootstrap dom elements

Remove bootstrap dom elements

--- src/golden_kestrel/core.cljs
+++ src/golden_kestrel/core.cljs
@@ -42,76 +42,53 @@
 (defn embed-form [data owner]
   (let [change-data (partial update-app data)]
     (dom/form
-      #js {:className "form-horizontal"}
-      (dom/div
-        #js {:className "control-group"}
-        (dom/label #js {:className "control-label"}
-                   "Badge type")
-        (dom/div
-          #js {:className "controls"}
-          (dom/select #js {:ref "badgeType"
-                           :value (:badge-type data)
-                           :defaultValue (:badge-type data)
-                           :onChange (partial change-data :badge-type)}
-                      (dom/option #js {:value ""} "Default")
-                      (dom/option #js {:value "1"} "1")
-                      (dom/option #js {:value "4"} "4")
-                      (dom/option #js {:value "donut"} "Donut")
-                      (dom/option #js {:value "medium-donut"} "Medium donut")
-                      (dom/option #js {:value "large-donut"} "Large donut"))))
-      (dom/div
-        #js {:className "control-group"}
-        (dom/label #js {:className "control-label"}
-                   "Popover")
-        (dom/div
-          #js {:className "controls"}
-          (dom/select #js {:ref "popover"
-                           :value (:popover data)
-                           :defaultValue (if (= "" (:badge-details data))
-                                           (:popover data)
-                                           "")
-                           :onChange (partial change-data :popover)}
-                      (dom/option #js {:value ""} "None")
-                      (dom/option #js {:value "top"} "Top")
-                      (dom/option #js {:value "right"} "Right")
-                      (dom/option #js {:value "bottom"} "Bottom")
-                      (dom/option #js {:value "left"} "Left"))))
-      (dom/div
-        #js {:className "control-group"}
-        (dom/label #js {:className "control-label"}
-                   "Details")
-        (dom/div
-          #js {:className "controls"}
-          (dom/select #js {:ref "details"
-                           :value (:badge-details data)
-                           :defaultValue (if (= "" (:popover data))
-                                           (:badge-details data)
-                                           "")
-                           :onChange (partial change-data :badge-details)}
-                      (dom/option #js {:value ""} "None")
-                      (dom/option #js {:value "right"} "Right"))))
-      (dom/div
-        #js {:className "control-group"}
-        (dom/label #js {:className "control-label"}
-                   "Hide no mentions?")
-        (dom/div
-          #js {:className "controls"}
-          (dom/input #js {:ref "hideNoMentions"
-                          :type "checkbox"
-                          :checked (:hide-no-mentions data)
-                          :onChange (partial change-data :hide-no-mentions)}
-                     nil)))
-      (dom/div
-        #js {:className "control-group"}
-        (dom/label #js {:className "control-label"}
-                   "DOI")
-        (dom/div
-          #js {:className "controls"}
-          (dom/input #js {:ref "doi"
-                          :type "text"
-                          :size "40"
-                          :defaultValue (:doi data)
-                          :onChange (partial change-data :doi)} nil))))))
+      nil
+      (dom/fieldset
+        nil
+        (dom/label nil "Badge type")
+        (dom/select #js {:ref "badgeType"
+                         :value (:badge-type data)
+                         :defaultValue (:badge-type data)
+                         :onChange (partial change-data :badge-type)}
+                    (dom/option #js {:value ""} "Default")
+                    (dom/option #js {:value "1"} "1")
+                    (dom/option #js {:value "4"} "4")
+                    (dom/option #js {:value "donut"} "Donut")
+                    (dom/option #js {:value "medium-donut"} "Medium donut")
+                    (dom/option #js {:value "large-donut"} "Large donut"))
+        (dom/label nil "Popover")
+        (dom/select #js {:ref "popover"
+                         :value (:popover data)
+                         :defaultValue (if (= "" (:badge-details data))
+                                         (:popover data)
+                                         "")
+                         :onChange (partial change-data :popover)}
+                    (dom/option #js {:value ""} "None")
+                    (dom/option #js {:value "top"} "Top")
+                    (dom/option #js {:value "right"} "Right")
+                    (dom/option #js {:value "bottom"} "Bottom")
+                    (dom/option #js {:value "left"} "Left"))
+        (dom/label nil "Details")
+        (dom/select #js {:ref "details"
+                         :value (:badge-details data)
+                         :defaultValue (if (= "" (:popover data))
+                                         (:badge-details data)
+                                         "")
+                         :onChange (partial change-data :badge-details)}
+                    (dom/option #js {:value ""} "None")
+                    (dom/option #js {:value "right"} "Right"))
+        (dom/label nil "Hide no mentions?")
+        (dom/input #js {:ref "hideNoMentions"
+                        :type "checkbox"
+                        :checked (:hide-no-mentions data)
+                        :onChange (partial change-data :hide-no-mentions)}
+                   nil)
+        (dom/label nil "DOI")
+        (dom/input #js {:ref "doi"
+                        :type "text"
+                        :size "40"
+                        :defaultValue (:doi data)
+                        :onChange (partial change-data :doi)} nil)))))

 (defn find-or-create-element
   [root class-name]


added cypher dependency

added cypher dependency

--- components/neo4j/project.clj
+++ components/neo4j/project.clj
@@ -6,5 +6,6 @@
             :dependencies [[gorillalabs.tesla/core :version]
                            [com.taoensso/timbre "4.6.0"]
                            [gorillalabs/neo4j-clj "0.3.1-SNAPSHOT"]
+                           [org.neo4j/neo4j-cypher "3.1.3"]
                            ])


added list-indexes

added list-indexes

--- src/karras.clj
+++ src/karras.clj
@@ -246,3 +246,5 @@
   [#^DBCollection collection kw]
   (.dropIndex collection (name kw)))

+(defn list-indexes [#^DBCollection collection]
+  (map to-clj (.getIndexInfo collection)))


reword docs

reword docs

--- src/logfmt.clj
+++ src/logfmt.clj
@@ -18,7 +18,8 @@

 (defn format-pairs
   "helper function for out and err
-   expands any literal values into string values"
+   expands any literal values into string values, removing string concatenation
+   at runtime"
   [pairs]
   (let [partitioned-pairs (partition 2 pairs)]
     `(str
@@ -41,24 +42,23 @@
                    (conj out (str (name k) "=" v))))))))))

 (defmacro out
-  "formats a static pair of keys/values and logs it to stdout specifically
-  designed for speed - at compile time it expands into a java.String.format
-  call
+  "formats a static pair of keys/values and logs it to stdout. Specifically
+   designed for speed - does a bunch of string concatenation at compile time

-  (out :foo a) expands to
+  (out :foo a) expands to something like
   (println (str \"foo= \" a))

-  (out :foo a :bar 1) expands to
+  (out :foo a :bar 1) expands to something like
   (println (str \"foo= \" a \" bar=1\"))
   "
   [& pairs]
   `(println ~(format-pairs pairs)))

 (defmacro err
-  "formats a static pair of keys/values and logs it to stderr specifically
-  designed for speed - at compile time it expands into a java.String.format
-  call
-  expands exactly like logfmt/out, except it prints to stderr"
+  "formats a static pair of keys/values and logs it to stderr. Specifically
+   designed for speed - does a bunch of string concatenation at compile time
+
+   expands exactly like logfmt/out, except it prints to stderr"
   [& pairs]
   (binding [*out* *err*]
     `(println ~(format-pairs pairs))))


Tentacles won't let us use oauth-token in defaults now

--- src/tyrant/store.clj
+++ src/tyrant/store.clj
@@ -20,6 +20,14 @@
 (def ^:private organisation
   (env :github-organisation))

+(def ^:private github-options
+  {:oauth-token (env :github-auth-token)})
+
+(defn merge-options
+  [options]
+  (merge github-options
+         options))
+
 (defn- busted?
   [response]
   (if-let [status (:status response)]
@@ -43,7 +51,7 @@
   [environment application]
   (try
     (let [repo-name (repo-name application environment)
-          commits (repos/commits organisation repo-name)]
+          commits (repos/commits organisation repo-name github-options)]
       (map extract-commit-info (remove empty? commits)))
     (catch Exception e
       (with-logging-context {:application application
@@ -80,7 +88,7 @@
   (let [repo-name (repo-name application environment)
         ref-map (create-ref-map environment application commit)
         options (merge ref-map {:str? true})
-        response (repos/contents organisation repo-name (str category ".json") options)]
+        response (repos/contents organisation repo-name (str category ".json") (merge-options options))]
     (if-let [data (:content response)]
       (let [hash (hash-from (:url response))]
         {:hash hash
@@ -100,7 +108,7 @@
 (defn all-repositories
   "Gets all repositories in the organisation in Github."
   []
-  (let [response (repos/org-repos organisation {:all_pages true})]
+  (let [response (repos/org-repos organisation (merge-options {:all_pages true}))]
     (when-not (busted? response)
       (doall (map extract-repo-info (remove empty? response))))))

@@ -119,7 +127,7 @@
   (try
     (let [repo-name (repo-name application environment)
           options {:auto_init true :has-downloads false :has-issues false :has-wiki false :public false}
-          response (repos/create-org-repo organisation repo-name options)]
+          response (repos/create-org-repo organisation repo-name (merge-options options))]
       (if (busted? response)
         (do
           (with-logging-context {:response response}
@@ -137,7 +145,7 @@
 (defn- github-working?
   []
   (try
-    (let [response (repos/org-repos organisation)]
+    (let [response (repos/org-repos organisation github-options)]
       (not (busted? response)))
     (catch Exception e
       false)))
@@ -180,7 +188,7 @@
     (let [repo-name (repo-name application environment)
           tree (properties-tree application environment)
           options {}
-          response (data/create-tree organisation repo-name tree options)]
+          response (data/create-tree organisation repo-name tree (merge-options options))]
       (if (busted? response)
         (do
           (with-logging-context {:response response}
@@ -202,7 +210,7 @@
           date (fmt/unparse (fmt/formatters :date-time-no-ms) (time/now))
           info {:date date :email "mixradiobot@gmail.com" :name "Mix Radio Bot"}
           options {:author info :committer info :parents []}
-          response (data/create-commit organisation repo-name "Initial commit" tree options)]
+          response (data/create-commit organisation repo-name "Initial commit" tree (merge-options options))]
       (if (busted? response)
         (do
           (with-logging-context {:response response}
@@ -223,7 +231,7 @@
   (try
     (let [repo-name (repo-name application environment)
           options {:force true}
-          response (data/edit-reference organisation repo-name "heads/master" commit options)]
+          response (data/edit-reference organisation repo-name "heads/master" commit (merge-options options))]
       (if (busted? response)
         (do
           (with-logging-context {:response response}


Now to D19P2...

Now to D19P2...

--- src/adventofcode/solutions.clj
+++ src/adventofcode/solutions.clj
@@ -826,3 +826,11 @@
       src)
     ))

+;attempt on part 2 - find longest match first etc... (search on subreddit for day 19 part 2)
+(let [input (day-input-line-seq 19)
+      size (count input)
+      replacements (map #(let [[_ from to] (first (re-seq #"(\w+) => (\w+)" %))]
+                          [from to]) (take (- size 2) input))
+      s-reps (sort-by second #(> (count %) (count %2)) replacements)
+      src (last input)]
+  (first (drop-while #(= -1 (.indexOf src (second %))) s-reps)))


Update API doc.

Update API doc.

--- src/afterglow/effects/cues.clj
+++ src/afterglow/effects/cues.clj
@@ -97,14 +97,12 @@
     If not supplied, 100 is assumed.

   * `:start` specifies the value to assign to the variable at the
-    start of the cue, if any. This is honored only for temporary
-    variables introduced for the cue, in other words when `:key` is
-    given with a string rather than a keyword.
+    start of the cue, if any.

   * `:type` identifies the type of the variable, to help formatting
-    its display. Supported values are `:integer`, `:float`, possibly
-    others in the future. If omitted or unrecognized, `:float` is
-    assumed.
+    its display. Supported values are `:integer`, `:float`, and
+    `:color`. Other types may be supported in the future. If omitted or
+    unrecognized, `:float` is assumed.

   * `:centered` supplied with a true value requests that the gauge
     displayed when adjusting this variable's value be like a pan


Normalize atom-lookup names

Normalize atom-lookup names

--- src/atom_finder/classifier.clj
+++ src/atom_finder/classifier.clj
@@ -49,8 +49,8 @@
    (ValidatedAtom :reversed-subscript        reversed-subscript-atom?    (default-finder reversed-subscript-atom?))
    (ValidatedAtom :literal-encoding          literal-encoding-atom?      (default-finder literal-encoding-atom?))
    (ValidatedAtom :post-increment            post-*crement-atom?         (default-finder post-*crement-atom?))
-   (ValidatedAtom :comma                     comma-operator-atom?        (default-finder comma-operator-atom?))
-   (ValidatedAtom :curly-braces              omitted-curly-braces-atom?  (default-finder omitted-curly-braces-atom?))
+   (ValidatedAtom :comma-operator            comma-operator-atom?        (default-finder comma-operator-atom?))
+   (ValidatedAtom :omitted-curly-braces      omitted-curly-braces-atom?  (default-finder omitted-curly-braces-atom?))
    (ValidatedAtom :assignment-as-value       assignment-as-value-atom?   (default-finder assignment-as-value-atom?))
    (ValidatedAtom :macro-operator-precedence macro-def-precedence-atom?  macro-operator-precedence-atoms)
    ]


cleanup model

cleanup model

--- src/babel/english/grammar.cljc
+++ src/babel/english/grammar.cljc
@@ -550,11 +550,7 @@
          :lookup (fn [arg]
                    (analyze arg lexicon))
          :morph morph
-         :morph-ps fo-ps
-         ;; TODO: remove: not used
-         :morph-walk-tree (fn [tree]
-                            (merge tree
-                                   (morph-walk-tree tree)))}]
+         :morph-ps fo-ps}]
     (assoc model
           :generate-fn
           (fn [spec]


"cry" is intransitive

"cry" is intransitive

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -491,7 +491,8 @@
                       :sem {:pred :create}}}

    "cry" {:synsem {:cat :verb
-                    :sem {:pred :cry}}}
+                   :sem {:pred :cry}
+                   :subcat {:2 '()}}}

    "cut" {:english {:past "cut"
                     :participle "cutting"}


add semantics for "attend"

add semantics for "attend"

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -110,6 +110,7 @@
                           :pred :at}}})

    "attend" {:synsem {:cat :verb
+                      :sem {:pred :attend}
                       :subcat {:1 {:cat :noun
                                    :sem {:human true}}
                                :2 {:cat :noun


replace "s'" with "se" since the apostrophe interferes with SQL

--- src/babel/francais/lexicon.clj
+++ src/babel/francais/lexicon.clj
@@ -531,7 +531,7 @@
                                        :reflexive true
                                        :sem subject-semantics}}}})

-  "s'appeler" (let [subject-semantics (ref {:human true})
+  "se appeler" (let [subject-semantics (ref {:human true})
                     subject-agr (ref :top)]
                 {:synsem {:cat :verb
                           :essere true
@@ -548,7 +548,7 @@
                                        :reflexive true
                                        :sem subject-semantics}}}})

-  "s'endormir" (let [subject-semantics (ref {:human true})
+  "se endormir" (let [subject-semantics (ref {:human true})
                     subject-agr (ref :top)]
                 {:synsem {:cat :verb
                           :essere true
@@ -563,7 +563,7 @@
                                        :reflexive true
                                        :sem subject-semantics}}}})

-  "s'énerver" (let [subject-semantics (ref {:human true})
+  "se énerver" (let [subject-semantics (ref {:human true})
                     subject-agr (ref :top)]
                 {:synsem {:cat :verb
                           :essere true
@@ -578,7 +578,7 @@
                                        :reflexive true
                                        :sem subject-semantics}}}})

-  "s'ennuyer" (let [subject-semantics (ref {:human true})
+  "se ennuyer" (let [subject-semantics (ref {:human true})
                     subject-agr (ref :top)]
                 {:synsem {:cat :verb
                           :essere true


Highlight the email text input if they click submit without giving us an email.

--- src/circle/web/views/index.clj
+++ src/circle/web/views/index.clj
@@ -64,14 +64,16 @@
 (defpartial signupform [& content]
    [:div.move-right
      [:div.blue-box
-       [:h2.takepart "Sign up for the beta"]
-         [:p.whenready "We'll email you when we're ready."]
-         [:form {:action "/" :method "POST"}
+      [:h2.takepart "Sign up for the beta"]
+      [:p.whenready "We'll email you when we're ready."]
+      [:form {:action "/"
+              :method "POST"
+              :onsubmit "if (this.email.value == \"Email address\") { this.email.style.background = 'red'; return false; }"}
            [:fieldset#actualform
              (unordered-list
                [(text-field {:id "email"
                              :type "text"
-                             :onfocus "if (this.value == 'Email address') { this.value=''};"
+                             :onfocus "this.style.background = 'white'; if (this.value == 'Email address') { this.value=''};"
                              :onblur "if (this.value == '') { this.value = 'Email address'};"}
                              "email" "Email address")
                 (check-box {:id "contact"


Add allow-robots? config var

Add allow-robots? config var

--- src/clj/clojuredocs/config.clj
+++ src/clj/clojuredocs/config.clj
@@ -12,4 +12,6 @@

 (def cljs-dev? (env/bool :cljs-dev false))

+(def allow-robots? (env/bool :allow-robots true))
+
 (defn url [& s] (apply str base-url s))


Fix nil issue thx to Hiram

Fix nil issue thx to Hiram

--- src/clj/communitics/server.clj
+++ src/clj/communitics/server.clj
@@ -27,7 +27,8 @@
     (println ";; Starting database")
     (let [conn (connect-to-database uri)]
       (assoc this :connection conn)
-      (println "connected to " conn)))
+      ;(println "connected to " conn)
+      ))

   (stop [this]
     (println ";; Stopping database")
@@ -49,10 +50,12 @@
     (println ";; Stopping github crawler"))
   )

+
 (defn find-countries [database]
   (d/q '[:find ?name
          :where [?e :db/ident ?name]]
        (d/db (:connection database))))
+

 (defn sum [req]
   {:status 200
@@ -75,7 +78,7 @@
       api))

-(defrecord WebServer [github-crawler database port]
+(defrecord WebApp [jetty database port]
   component/Lifecycle
   (start [component]
     (do
@@ -102,7 +105,11 @@
 (defn prod-system [config-options]
   (component/system-map
     :database (make-database (:datomic-uri config-options))
-    :github-crawler (make-github-crawler config-options)))
+    :github-crawler (component/using
+                      (map->GithubCrawler {:serveraddress (:github-address config-options)})
+                      [:database])
+    :web-app (component/using
+               (map->WebApp {:port 10555}) [:database])))

 (defn -main [& [port]]


Handle comments in let form.

Handle comments in let form.

--- src/clj/quil_site/snippets.clj
+++ src/clj/quil_site/snippets.clj
@@ -27,8 +27,11 @@
         code (subs code 1 (dec (count code)))]
     (-> (zp/zprint-str code 80 zprint-options)
         ; Convert all (comment "foo") lines into
-        ; comment ; foo.
-        (string/replace #"\(comment \"(.+)\"\)\n" "; $1\n"))))
+        ; comment ; foo. Also handle cases like
+        ; (let [_ (commment "foo")
+        ;       abc 123]
+        ; It'll remove _ as well.
+        (string/replace #"(_ )?\(comment \"(.+)\"\)\n" "; $2\n"))))

 (def snippets-by-function (group-snippets-by-function snippets))


Change indentation

Change indentation

--- src/clj/rumahsewa141/views.clj
+++ src/clj/rumahsewa141/views.clj
@@ -11,11 +11,7 @@

 (defn describe-transaction
   "Describe transaction in words understandable by human."
-  [{:keys [username
-           rent
-           internet
-           others
-           transaction_timestamp]}]
+  [{:keys [username rent internet others transaction_timestamp]}]
   {:description (apply str (drop-last (str username
                                            " "
                                            (find-verb rent internet others)


Disable chunking of 2bit read-all-sequences

--- src/cljam/io/twobit/reader.clj
+++ src/cljam/io/twobit/reader.clj
@@ -119,13 +119,21 @@
        (.rewind cb)
        (.toString cb)))))

+(defn- read-all-sequences*
+  [rdr chrs option]
+  (when (seq chrs)
+    (let [[{:keys [name]} & nxt] chrs]
+      (lazy-seq
+       (cons {:name name
+              :sequence (read-sequence rdr {:chr name} option)}
+             (read-all-sequences* rdr nxt option))))))
+
 (defn read-all-sequences
   "Reads all sequences in file."
   ([rdr]
    (read-all-sequences rdr {}))
   ([^TwoBitReader rdr option]
-   (for [{:keys [name offset]} (.file-index rdr)]
-     {:name name :sequence (read-sequence rdr {:chr name} option)})))
+   (read-all-sequences* rdr (.file-index rdr) option)))

 (defn read-indices
   "Reads metadata of indexed sequences."


Disables vectorize-parsed-pgn in Clojure.

This function is only used in ClojureScript mode anyway, as a workaround
for what looks like a bug in instaparse-cljs.

--- src/clojure/clj_chess/pgn.cljc
+++ src/clojure/clj_chess/pgn.cljc
@@ -82,20 +82,21 @@
                   "?!" 6
                   "$" (read-string (second rest)))])})

-(defn- vectorize-parsed-pgn
-  "Workaround for bug (?) in instaparse-cljs, where some parse tree entries
-  turn out to be of type instaparse.auto-flatten-seq/FlattenOnDemandVector
-  rather than vectors."
-  [parsed-pgn]
-  (cond
-    (not (coll? parsed-pgn))
-    parsed-pgn
+#?(:cljs
+   (defn- vectorize-parsed-pgn
+     "Workaround for bug (?) in instaparse-cljs, where some parse tree entries
+     turn out to be of type instaparse.auto-flatten-seq/FlattenOnDemandVector
+     rather than vectors."
+     [parsed-pgn]
+     (cond
+       (not (coll? parsed-pgn))
+       parsed-pgn

-    (= (type parsed-pgn) instaparse.auto-flatten-seq/FlattenOnDemandVector)
-    (vec parsed-pgn)
+       (= (type parsed-pgn) instaparse.auto-flatten-seq/FlattenOnDemandVector)
+       (vec parsed-pgn)

-    :else (vec (cons (first parsed-pgn)
-                     (map vectorize-parsed-pgn (rest parsed-pgn))))))
+       :else (vec (cons (first parsed-pgn)
+                        (map vectorize-parsed-pgn (rest parsed-pgn)))))))

 (defn parse-pgn [pgn & [start]]
   (let [parsed-pgn (pgn-parser pgn :start (or start :game))]


Added mock echo method for logging in with group access.

--- src/cmr/transmit/echo/mock.clj
+++ src/cmr/transmit/echo/mock.clj
@@ -24,4 +24,18 @@
   [context acl]
   (let [[status] (r/rest-post context "/acls" (c/cmr-acl->echo-acl acl))]
     (when-not (= status 201)
-      (r/unexpected-status-error! status nil))))+      (r/unexpected-status-error! status nil))))
+
+(defn login-with-group-access
+  "Logs into mock echo and returns the token. The group guids passed in will be returned as a part
+  of the current_sids of the user"
+  [context username password group-guids]
+  (let [token-info {:token {:username username
+                            :password password
+                            :client_id "CMR Internal"
+                            :user_ip_address "127.0.0.1"
+                            :group_guids group-guids}}
+        [status parsed body] (r/rest-post context "/tokens" token-info)]
+    (if (= 201 status)
+      (get-in parsed [:token :id])
+      (r/unexpected-status-error! status body))))


Added comments.

Added comments.

--- src/cmr/umm/dif/collection.clj
+++ src/cmr/umm/dif/collection.clj
@@ -92,6 +92,7 @@
             {:keys [insert-time update-time]} :data-provider-timestamps
             :keys [entry-id entry-title temporal organizations science-keywords platforms product-specific-attributes
                    projects related-urls spatial-coverage]} collection
+           ;; DIF only has range-date-times, so we ignore the temporal field if it is not of range-date-times
            temporal (when (seq (:range-date-times temporal)) temporal)
            emit-fn (if indent? x/indent-str x/emit-str)]
        (emit-fn


Cookies not parsed if :cookies key exists in request

--- src/compojure/http/request.clj
+++ src/compojure/http/request.clj
@@ -101,7 +101,9 @@
 (defn assoc-cookies
   "Associate cookies with a request map."
   [request]
-  (assoc request :cookies (get-cookies request)))
+  (if (contains? request :cookies)
+    request
+    (assoc request :cookies (get-cookies request))))

 (defn with-cookies
   "Decorator that adds cookies to a request map."


Fix wrong comments for attribute exploration

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

--- src/conexp/fca/exploration.clj
+++ src/conexp/fca/exploration.clj
@@ -217,7 +217,7 @@
              (= counterexamples :abort)
              (recur implications nil ctx) ; forget all other sets
              ;;
-             counterexamples
+             counterexamples            ; add counterexample
              (let [new-objs (map first counterexamples)]
                ;; check that new names are not there already
                (when (exists [g new-objs] (contains? (objects ctx) g))
@@ -231,7 +231,7 @@
                                            (set-of [g m] [[g ms] counterexamples,
                                                           m ms])))))
              ;;
-             true                       ; add counterexample
+             true                       ; add implication
              (recur (conj implications new-impl)
                     (next-closed-set (attributes ctx)
                                      (clop-by-implications (conj implications new-impl))


update method

update method

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>

--- src/emulator_chip8/opcode.cljc
+++ src/emulator_chip8/opcode.cljc
@@ -1,5 +1,5 @@
 (ns emulator-chip8.opcode
-;;  #?(:cljs (:require-macros [emulator-chip8.opcode :refer [defop to-opcode-func]]))
+  ;;  #?(:cljs (:require-macros [emulator-chip8.opcode :refer [defop to-opcode-func]]))
   )

 ;; #?(:clj
@@ -16,6 +16,35 @@
 ;;      (let [n  (symbol (str name))]
 ;;        `(~n)
 ;;        )))
+
+(def opcode-table (atom #{}))
+
+(defmacro defop
+  [opcode args & body]
+  (let [key (keyword (name opcode))
+        pname (symbol (str "opcode-" (name opcode)))
+        ]
+    `(defn ~pname [~@args] ~@body)
+    (swap! opcode-table conj key)
+    ))
+
+(defop :6XNN
+  []
+  ;;(println "ad")
+  )
+
+(defop :8XY3
+  []
+  ;;(println "ad")
+  )
+
+
+(deref opcode-table)
+(reset! opcode-table #{})
+
+(swap! opcode-table conj (keyword (name :aaa)))
+
+(swap! opcode-table conj :as)

 (defn make-opcode-match-list
   [opcode]
@@ -166,14 +195,14 @@

 (defn find-match-handler
   "Search for matching handler in handler list.
-If nothing find, return nil else return keyword."
+  If nothing find, return nil else return keyword."
   [handler opcode]
   (str "opcode-" (name (some (make-opcode-sets opcode) (keys handler))) )
   )

 (defn make-handler-args
   "Parse the code to find how many VX, VY, NNN, NN, N
-and create argument lists."
+  and create argument lists."
   [opcode]
   (let [code (format "%04X" opcode)]
     {:NNN (subs code 1 4)
@@ -194,7 +223,7 @@

 (defn find-match-handler
   "Search for matching handler in handler list.
-If nothing find, return nil else return keyword."
+  If nothing find, return nil else return keyword."
   [handler opcode]
   (some (make-opcode-sets opcode) (keys handler)))


doc more fns, list all repos for hooks cmd

--- src/gh_waiting_room/github.clj
+++ src/gh_waiting_room/github.clj
@@ -18,6 +18,8 @@

 ;;; github data fns
 (defn- issue-filter
+  "Filter fn used to only keep public issues that match allowed repository names
+   and allowed label values."
   [issue]
   (and
    (not (get-in issue [:repository :private]))
@@ -28,7 +30,9 @@
            (map :name (:labels issue))))
      (= [] (:labels issue)))))

-(defn ->issue [issue]
+(defn ->issue
+  "Converts an issue from github into a simplified issue used throughout this app."
+  [issue]
   {:id (format "%s#%s"
                (get-in! issue [:repository :full_name])
                (get! issue :number))
@@ -45,7 +49,9 @@
    :created (or (re-find #"\d{4}-\d\d-\d\d"(get! issue :created_at))
                 (throw (ex-info "Failed to parse date from an issue" {:issue issue})))})

-(defn viewable-issues [db]
+(defn viewable-issues
+  "Filter allowed issues, simplify their format and prepare them to be viewed on a web page."
+  [db]
   (->> (:issues db)
        (filter issue-filter)
        (map ->issue)
@@ -53,7 +59,9 @@
        (map-indexed (fn [num elem]
                       (assoc elem :position (inc num))))))

-(defn- comment-body [issue]
+(defn- comment-body
+  "Creates the comment body for an auto comment kicked off by an issue being opened or closed."
+  [issue]
   (str
    (if (= (:type issue) "pull request")
      "Thanks for your pull request!"
@@ -64,10 +72,12 @@

 ;;; github fns
 (defn fetch-gh-issues
+  "Fetches all issues that authenticated user has push access to, public or private."
   []
   (my-issues (merge {:filter "all" :all-pages true} (gh-auth))))

-(defn create-webhook [user name]
+(defn create-webhook
+  [user name]
   (let [result
         (create-hook user name "web"
                      {:url (full-url-for "/webhook") :content_type "json"}
@@ -76,14 +86,14 @@
                      user name (:id result)))))

 (defn repo-hooks
-  "List hooks for an individual repository"
+  "List hooks for an individual repository."
   [user name]
   (->>
    (hooks user name (gh-auth))
    (map (fn [h]
           {:url (get-in h [:config :url]) :id (:id h) :name (:name h)}))))

-(defn list-repos
+(defn- list-repos
   []
   (let [all-repos (repos (assoc (gh-auth) :type "public" :all-pages true))
         filter-fn (if (hook-forks) identity (comp not :fork))]
@@ -91,16 +101,15 @@
          (filter filter-fn)
          (map (fn [repo] {:name (get! repo :name) :owner (get-in! repo [:owner :login])})))))

-(defn list-repos-with-hooks
+(defn- list-repos-with-hooks
   []
   (map #(assoc % :hooks (repo-hooks (:owner %) (:name %))) (list-repos)))

 (defn all-hooks
-  "List hooks by repository for all public repositories with hooks"
+  "List hooks by repository for public repositories owned by user."
   []
   (let [hook-id #(or (:url %) (:name %))]
     (->> (list-repos-with-hooks)
-         (filter #(seq (:hooks %)))
          (map #(assoc % :hooks (map hook-id (:hooks %)))))))

 (defn delete-webhook
@@ -109,14 +118,16 @@
     (println (format "Deleted webhook for %s/%s" user name))))

 (defn create-all-webhooks
-  "Creates webhooks for all repositories that don't have one in $GITHUB_APP_DOMAIN"
+  "Creates webhooks for all repositories that don't have one in $GITHUB_APP_DOMAIN."
   []
   (let [has-gh-webhook #(some #{(full-url-for "/webhook")} (map :url (:hooks %)))
         repos (remove has-gh-webhook (list-repos-with-hooks))]
     (doseq [repo repos]
       (create-webhook (:owner repo) (:name repo)))))

-(defn create-issue-comment [db issue-id issue-num]
+(defn create-issue-comment
+  "Creates a comment for an issue given a map (db of issues)."
+  [db issue-id issue-num]
   (let [issue (or
                (some #(and (= (:id %) issue-id) %) (viewable-issues db))
                (throw (ex-info "No issue found for webhook" {:issue-id issue-id})))


Logs watch response status field

Logs watch response status field

--- scheduler/src/cook/kubernetes/api.clj
+++ scheduler/src/cook/kubernetes/api.clj
@@ -142,7 +142,7 @@
         (process-watch-response! state-atom item type key-fn callbacks)
         (throw (ex-info "Encountered nil object on watch response"
                         {:watch-object item
-                         :watch-response watch-response
+                         :watch-status (.-status watch-response)
                          :watch-type type}))))))

 (defn get-pod-namespaced-key


Make R/pp works like soy (kinda)

Make R/pp works like soy (kinda)

--- etc/repl.clj
+++ etc/repl.clj
@@ -14,7 +14,11 @@

 (ns.repl/disable-reload! *ns*)
-(def ^{:doc "Pretty print a thing"} pp clojure.pprint/pprint)
+
+(defn pp
+  [thing]
+  (clojure.pprint/pprint thing)
+  thing)

 (defn help [& n]


Fix #128: Restores working lein repl for cljx projects

--- src/leiningen/new/chestnut.clj
+++ src/leiningen/new/chestnut.clj
@@ -45,7 +45,8 @@

 (defn project-dev-deps [opts]
   (cond-> []
-          (speclj? opts) (conj "speclj \"3.2.0\"")))
+          (speclj? opts) (conj "speclj \"3.2.0\"")
+          (cljx? opts) (conj "com.keminglabs/cljx \"0.6.0\" :exclusions [org.clojure/clojure]")))

 (defn project-plugins [opts]
   (cond-> []


Fix typo namspace -> namespace

Fix typo namspace -> namespace

--- src/leiningen/new/figwheel.clj
+++ src/leiningen/new/figwheel.clj
@@ -41,7 +41,7 @@
   (do
     (when (= name "figwheel")
       (main/abort
-       (str "Cannot name a figwheel project \"figwheel\" the namspace will clash.\n"
+       (str "Cannot name a figwheel project \"figwheel\" the namespace will clash.\n"
             "Please choose a different name, maybe \"tryfig\"?")))
     (clean-opts valid-options opts) ;; Check options for errors
     (let [data {:name name


Simplify request header logic

Simplify request header logic

The latest version of one.browser.remote no longer requires the custom
request header logic previously implemented in one.repmax.mongohq.

--- src/app/cljs/one/repmax/mongohq.cljs
+++ src/app/cljs/one/repmax/mongohq.cljs
@@ -49,7 +49,7 @@

 (defn- request-headers [content-type]
   (if (= content-type :json)
-    (goog.structs.Map. (clj->js {"Content-Type" "application/json"}))))
+    {"Content-Type" "application/json"}))

 (defn- request-content [content-type content]
   (if (= content-type :json)


test implements ISeq before native IIndexed, huge perf hit to go through native-satisfies? first

--- src/main/cljs/cljs/core.cljs
+++ src/main/cljs/cljs/core.cljs
@@ -1612,11 +1612,11 @@
       (when (< n (.-length coll))
         (aget coll n))

+      (implements? ISeq coll)
+      (linear-traversal-nth coll n)
+
       (native-satisfies? IIndexed coll)
       (-nth coll n)
-
-      (satisfies? ISeq coll)
-      (linear-traversal-nth coll n)

       :else
       (throw (js/Error. (str "nth not supported on this type "
@@ -1642,11 +1642,11 @@
         (aget coll n)
         not-found)

+      (implements? ISeq coll)
+      (linear-traversal-nth coll n not-found)
+
       (native-satisfies? IIndexed coll)
       (-nth coll n)
-
-      (satisfies? ISeq coll)
-      (linear-traversal-nth coll n not-found)

       :else
       (throw (js/Error. (str "nth not supported on this type "


Fix footer on mobile

Fix footer on mobile

--- src/clj/clojuredocs/pages/common.clj
+++ src/clj/clojuredocs/pages/common.clj
@@ -134,32 +134,37 @@
         content]]]
      [:div.sticky-push]]
     [:footer
-     [:div.divider
-      "- ❦ -"]
-     [:div.ctas
-      "Brought to you by "
-      [:a {:href "https://twitter.com/heyzk"} "@heyzk"]
-      ". "
-      "  / "
-      [:iframe {:src "/github-btn.html?user=zk&repo=clojuredocs&type=watch&count=true"
-                :allowtransparency "true"
-                :frameborder "0"
-                :scrolling "0"
-                :width "80"
-                :height "20"}]
-      [:iframe {:src "/github-btn.html?user=zk&repo=clojuredocs&type=fork&count=true"
-                :allowtransparency "true"
-                :frameborder "0"
-                :scrolling "0"
-                :width "80"
-                :height "20"}]
-      [:a.twitter-share-button {:href "https://twitter.com/share"
-                                :data-url "http://clojuredocs.org"
-                                :data-text "Community-powered docs and examples for #Clojure"
-                                :data-via "heyzk"}
-       "Tweet"]
-      [:script
-       "!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');"]]]
+     [:div.container
+      [:div.row
+       [:div.col-sm-12
+        [:div.divider
+         "- ❦ -"]]]
+      [:div.row
+       [:div.ctas
+        [:div.col-sm-6.left
+         "Brought to you by "
+         [:a {:href "https://twitter.com/heyzk"} "@heyzk"]
+         ". "]
+        [:div.col-sm-6.right
+         [:iframe {:src "/github-btn.html?user=zk&repo=clojuredocs&type=watch&count=true"
+                   :allowtransparency "true"
+                   :frameborder "0"
+                   :scrolling "0"
+                   :width "80"
+                   :height "20"}]
+         #_[:iframe {:src "/github-btn.html?user=zk&repo=clojuredocs&type=fork&count=true"
+                   :allowtransparency "true"
+                   :frameborder "0"
+                   :scrolling "0"
+                   :width "80"
+                   :height "20"}]
+         [:a.twitter-share-button {:href "https://twitter.com/share"
+                                   :data-url "http://clojuredocs.org"
+                                   :data-text "Community-powered docs and examples for #Clojure"
+                                   :data-via "heyzk"}
+          "Tweet"]]]
+       [:script
+        "!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');"]]]]
     (when (env/bool :cljs-dev)
       [:script {:src "/js/fastclick.min.js"}])
     (when (env/bool :cljs-dev)


`timetable-row-not-empty?` - correct docstring

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -601,8 +601,8 @@
             ttRow)))

 (defn- timetable-row-not-empty?
-  "Returns true if there no lesson for a given day and row in `Timetable`.
-   Returns false otherwise."
+  "Returns true if there at least one lesson for a given day and row in
+   `Timetable`. Returns false otherwise."
   [day rowNum]
   (not (empty? (timetable-get-day-row day rowNum))))


Add submit email new action form by Enter pressing.

--- src/cljs/hatnik/web/client/form.cljs
+++ src/cljs/hatnik/web/client/form.cljs
@@ -2,7 +2,8 @@
   (:require [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]
             [hatnik.web.client.form-components :as widget]
-            [hatnik.web.client.app-state :as state])
+            [hatnik.web.client.app-state :as state]
+            [hatnik.web.client.z-actions :as action])
   (:use [jayq.core :only [$]]))

 (om/root widget/action-form-header state/app-state
@@ -25,3 +26,9 @@
                (.modal ($ :#iModalProject) "hide")
                (.modal ($ :#iModalProjectMenu) "hide"))))

+;; Submit new email action by Enter pressing
+(.keydown ($ :#iModal)
+          (fn [e]
+            (when (= 13 (.-keyCode e))
+              (action/send-new-email-action (:current-project (deref state/app-state))))))
+