server services

server services

--- src/clj/rksm/cloxp_com/server.clj
+++ src/clj/rksm/cloxp_com/server.clj
@@ -13,7 +13,7 @@

 (defonce log (agent []))

-(def debug true)
+(def debug false)

 (defn log-req
   [app]
@@ -31,7 +31,9 @@
 ; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 ; server connection, sending / receiving

-(declare register-channel find-channel channels app)
+(declare register-channel find-channel channels app
+         register-service-handler close-connection-service-handler
+         send-message-impl)

 (defrecord MessengerImpl [host port stop-fn receive-channel]
   m/IReceiver
@@ -40,47 +42,29 @@
                  (close! receive-channel)
                  (stop-fn :timeout 100))
   m/ISender
-  (send-message [this con msg]
-                (if-let [chan (or (-> msg :target find-channel)
-                                  (:channel m/*current-connection*)
-                                  con)]
-                  (try
-                    (http/send! chan (json/write-str msg))
-                    (catch Exception e (println e)))
-                  (throw (Exception. (str "Cannot find channel for target " (:target msg)))))))
+  (send-message [this con msg] (send-message-impl this con msg)))

 (defn create-messenger
   [& {:keys [port host], :or {port 8081 host "0.0.0.0"} :as opts}]
   (let [stop (http/run-server #'app {:port port :host host})
-        messenger (m/create-messenger "server-messenger"
-                                      (->MessengerImpl host port stop (chan)))]
-
-    (m/add-service messenger "register"
-                   (fn [server {:keys [sender data] :as msg}]
-                     (if m/*current-connection*
-                       (do
-                         (register-channel
-                          server (:channel m/*current-connection*)
-                          sender data)
-                         (m/answer server msg :OK false))
-                       (m/answer server msg
-                                 {:error (str "Cannot register connection for" sender)}
-                                 false))))
-
-    (m/add-service messenger "close-connection"
-                   (fn [server {{id :id} :data :as msg}]
-                     (if-let [con (if id
-                                    (find-channel id)
-                                    (:channel m/*current-connection*))]
-                       (do
-                         (go
-                          (<! (timeout 200))
-                          (-> con :channel (.serverClose 0)))
-                         (m/answer server msg :OK false))
-                       (m/answer server msg
-                                 {:error (str "cannot find channel for" id)}
-                                 false))))
+        services (merge (m/default-services)
+                        {"register" #'register-service-handler
+                         "close-connection" #'close-connection-service-handler})
+        messenger (m/create-messenger
+                   "server-messenger"
+                   (->MessengerImpl host port stop (chan))
+                   services)]
     messenger))
+
+(defn send-message-impl
+  [server con msg]
+  (if-let [chan (or (:channel m/*current-connection*)
+                    (-> msg :target find-channel)
+                    con)]
+    (try
+      (http/send! chan (json/write-str msg))
+      (catch Exception e (println e)))
+    (throw (Exception. (str "Cannot find channel for target " (:target msg))))))

 ; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 ; routing
@@ -168,6 +152,32 @@
   (swap! channels assoc id {:channel channel :data register-data}))

 ; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+; services
+
+(defn register-service-handler
+  [server {:keys [sender data] :as msg}]
+  (if m/*current-connection*
+    (do
+      (register-channel
+       server (:channel m/*current-connection*)
+       sender data)
+      (m/answer server msg :OK false))
+    (m/answer server msg
+              {:error (str "Cannot register connection for" sender)}
+              false)))
+
+(defn close-connection-service-handler
+  [server {{id :id} :data :as msg}]
+  (if-let [con (if id
+                 (find-channel id)
+                 (:channel m/*current-connection*))]
+    (try
+      (m/answer server msg :OK false)
+      (.serverClose con 200)
+      (catch Exception e (m/answer server msg {:error (str e)} false)))
+    (m/answer server msg
+              {:error (str "cannot find channel for" id)}
+              false)))

 (comment
  (start-server! :port 8082)


tweak to init filter when mounted

tweak to init filter when mounted

--- src/cljs/apollo/client/pages.cljs
+++ src/cljs/apollo/client/pages.cljs
@@ -44,6 +44,8 @@
     om/IWillMount
     (will-mount [_]
       (om/set-state! owner :keypress-chan (chan (dropping-buffer 1)))
+      (om/transact! (state/ref-post-filter)
+                    (fn [p] (assoc p :value nil)))
       (sub events/event-bus :keypress (om/get-state owner :keypress-chan))
       (go
         (loop []


Virus counters only present if :installed (handles Personal Workshop)

A Personal Workshop will host an inactive card (not "installed") and
put/manipulate power counters on it.  The :installed trait is used to
distinguish power counters on inactive virus cards from virus tokens on
installed virus cards.

--- src/cljs/netrunner/gameboard.cljs
+++ src/cljs/netrunner/gameboard.cljs
@@ -346,7 +346,8 @@
              [:span.cardname title]
              [:img.card.bg {:src url :onError #(-> % .-target js/$ .hide)}]]))
         [:div.counters
-         (when (pos? counter) (if (> (.indexOf subtype "Virus") -1)
+         (when (pos? counter) (if (and (:installed @cursor)
+                                       (> (.indexOf subtype "Virus") -1))
                                   [:div.darkbg.virus.counter counter]
                                   [:div.darkbg.counter counter]))
          (when (pos? rec-counter) [:div.darkbg.recurring.counter rec-counter])


Small simplifications and typo corrections

--- src/cljs/nonojure/puzzleview.cljs
+++ src/cljs/nonojure/puzzleview.cljs
@@ -55,10 +55,9 @@

 (defn pad [nums beg end value]
-  (-> []
-      (into (repeat beg value))
-      (into nums)
-      (into (repeat end value))))
+  (vec (concat (repeat beg value)
+               nums
+               (repeat end value))))

 (defn add-class-templ [el class]
   (update-in el [1 :class] str class))
@@ -69,7 +68,7 @@

 (defn add-thick-class
   "Adds thick-left and thick-right classes to every 5th element
-Basically it add thick-left to 0, 5, 10 element and thick-right to last one."
+  Basically it add thick-left to 0, 5, 10 element and thick-right to last one."
   [tds]
   (let [tds (map-indexed
              (fn [ind value]
@@ -170,19 +169,17 @@
         row-num (count rows)
         solution (for [r (range row-num)
                        :let [cells (sel (str ".r" r))]]
-                   (->> cells
-                     (map #(if (dommy/has-class? % "cell-clicked") 1 0))
-                     (into [])))]
+                   (mapv #(if (dommy/has-class? % "cell-clicked") 1 0) cells))]
     (vec solution)))

 (defn extract-numbers [row]
-  "Given a sequence containing 0s and 1s returns numbers of consequetive ones,
+  "Given a sequence containing 0s and 1s returns numbers of consecutive ones,
   i.e. given [1 0 0 1 1] will return [1 2]"
   (->> row
     (partition-by identity)
     (filter #(= 1 (first %)))
     (map count)
-    (into [])))
+    vec))

 (defn check-solution []
   "Returns true if current state of puzzle is a valid solution, false otherwise"
@@ -216,13 +213,13 @@

 (defn rate [diff]
   "Submits rating for puzzle id. Assumed to be called from rating dialog.
-  Puzzle ID is implicitely taken from dialog properties"
+  Puzzle ID is implicitly taken from dialog properties"
   (let [args (.-dialogArguments js/window)
         id (.-id args) ]
     (goog.net.XhrIo/send (str "/api/rate/" id "?difficulty=" diff) #(.close js/window))))

 (defn rate-dialog [id]
-  "Shows rate dialog for give puzzle id"
+  "Shows rate dialog for given puzzle id"
   (let [d-attrs (js-obj)
         _ (set! (.-id d-attrs) id)]
     (js/showModalDialog "rating" d-attrs "dialogWidth:250; dialogHeight:100; dialogLeft:860; dialogTop: 540; resizable: no")))


ideas

ideas

--- src/cljs/triboard/logic/game.cljs
+++ src/cljs/triboard/logic/game.cljs
@@ -52,5 +52,5 @@
   "Get the reachable games from the current position, by player and position"
   [game]
   (move/map-game-tree
-    (fn [next-turn] (conj game next-turn))
+    (fn [next-turn] (conj game next-turn))                  ;; TODO - create a real new game, and put the thing in cache (delay for each recursive game)
     (turn/available-turns (peek game))))


Remove unused ns

Remove unused ns

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -1,6 +1,5 @@
 (ns nightcode.editors
-  (:require [clojure.data :refer [diff]]
-            [clojure.java.io :as io]
+  (:require [clojure.java.io :as io]
             [clojure.string :as str :refer [join]]
             [flatland.ordered.map :as flatland]
             [nightcode.completions :as completions]


[#1890] Add ex-info message if original `cause` ex-data is nil

--- backend/src/akvo/lumen/lib/import/flow.clj
+++ backend/src/akvo/lumen/lib/import/flow.clj
@@ -30,7 +30,8 @@
             (<= version 3) (v3/dataset-columns (flow-common/form @survey formId)))
           (catch Throwable e
             (if-let [ex-d (ex-data e)]
-              (throw (ex-info (:cause e) (assoc ex-d :instance instance)))
+              (throw (ex-info (or (:cause e) (str "Null cause from instance: " instance))
+                              (assoc ex-d :instance instance)))
               (throw e)))))
       (records [this]
         (try
@@ -39,5 +40,6 @@
             (<= version 3) (v3/form-data headers-fn @survey formId))
           (catch Throwable e
             (if-let [ex-d (ex-data e)]
-              (throw (ex-info (:cause e) (assoc ex-d :instance instance)))
+              (throw (ex-info (or (:cause e) (str "Null cause from instance: " instance))
+                              (assoc ex-d :instance instance)))
               (throw e))))))))


Improved logging

Improved logging

--- backend/src/circle/backend/action/bash.clj
+++ backend/src/circle/backend/action/bash.clj
@@ -1,6 +1,5 @@
 (ns circle.backend.action.bash
   "functions for running bash on remote instances, and build actions for same."
-  (:use [arohner.utils :only (inspect)])
   (:require pallet.action-plan)
   (:use [circle.util.core :only (apply-map)])
   (:use [circle.backend.build :only (*env* log-ns build-log build-log-error)])
@@ -18,8 +17,9 @@
   (let [cmd (sh/emit-form body
                           :environment environment
                           :pwd pwd)
-        _ (build-log "running %s" body pwd environment cmd)
+        _ (build-log "running %s %s %s %s" body pwd environment cmd)
         result (ssh/remote-exec ssh-map cmd)]
+    (build-log "%s returned" (-> result :exit)) ;; only log exit, rest should be handled by ssh
     result))

 (defn ssh-map-for-build [build]


Add bench for directly wrapping

Add bench for directly wrapping

--- benchmarks/caesium/byte_bufs_benchmark.clj
+++ benchmarks/caesium/byte_bufs_benchmark.clj
@@ -10,6 +10,16 @@
   (let [c (byte-array (+ sb/macbytes (bb/buflen m)))]
     (sb/secretbox-easy-to-buf!
      (bb/->indirect-byte-buf c)
+     (bb/->indirect-byte-buf m)
+     (bb/->indirect-byte-buf n)
+     (bb/->indirect-byte-buf k))
+    c))
+
+(defn secretbox-easy-directly-wrap-byte-array
+  [m n k]
+  (let [c (byte-array (+ sb/macbytes (bb/buflen m)))]
+    (sb/secretbox-easy-to-buf!
+     (java.nio.ByteBuffer/wrap c)
      (bb/->indirect-byte-buf m)
      (bb/->indirect-byte-buf n)
      (bb/->indirect-byte-buf k))
@@ -29,6 +39,10 @@
   (println "byte array allocation, wrapped to byte buf")
   (bench (secretbox-easy-wrap-byte-array st/ptext st/n0 st/secret-key)))

+(deftest ^:benchmark directly-wrap-byte-array
+  (println "byte array allocation, directly wrapped to byte buf (no dispatch)")
+  (bench (secretbox-easy-directly-wrap-byte-array st/ptext st/n0 st/secret-key)))
+
 (deftest ^:benchmark unwrap-byte-buf
   (println "byte buf allocation, unwrapped to byte array")
   (bench (secretbox-easy-unwrap-byte-buf st/ptext st/n0 st/secret-key)))


1_3_1

--- src/sicp_tasks_on_clojure/chapter1_3_1.clj
+++ src/sicp_tasks_on_clojure/chapter1_3_1.clj
@@ -1,10 +1,11 @@
 (ns sicp-tasks-on-clojure.chapter1-3-1)

 (defn sum [term a next b]
-  (if (> a b)
-    0
-    (+ (term a)
-       (sum term (next a) next b))))
+  (loop [a a
+         acc 0]
+    (if (> a b)
+      acc
+      (recur (next a) (+ acc (term a))))))

 (defn cube [a]
   (* a a a))
@@ -30,3 +31,22 @@
           (* (/ h 3) (+ acc (yk k)))
           (recur (dec k) (+ acc (yk k))))))))

+(defn accumulate [combiner null-value term a next b]
+  (loop [a a
+         acc null-value]
+    (if (> a b)
+      acc
+      (recur (next a) (combiner acc (term a))))))
+
+(defn product [term a next b]
+  (accumulate * 1 term a next b))
+
+;(defn product [term a next b]
+;  (loop [a a
+;         acc 1]
+;    (if (> a b)
+;      acc
+;      (recur (next a) (* acc (term a))))))
+
+(defn factorial [n]
+  (product identity 1 inc n))


Handle bitmasks without enums

Handle bitmasks without enums

--- src/mavlink/mavlink_xml.clj
+++ src/mavlink/mavlink_xml.clj
@@ -142,7 +142,7 @@
                 (write-fn payload (translate-keyword mavlink fval)))
               (dotimes [i num-missing]
                 (write-fn payload 0))))
-          (if bitmask
+          (if (and bitmask enum-type)
             (gen-encode-bitmask write-fn name-key enum-type enums-by-group)
             (fn encode-it [mavlink payload message]
               (write-fn payload (translate-keyword mavlink (get message name-key 0)))))))


More factoring!

More factoring!

--- src/merkle_db/partition.clj
+++ src/merkle_db/partition.clj
@@ -230,6 +230,23 @@

 ;; ## Update Functions

+; TODO: find better pattern than passing limit and half-full around :\
+
+(defn- check-partition
+  "Check a partition for validity under the current parameters. Returns a tuple
+  containing output valid partitions and a new virtual tablet, if needed."
+  [store params limit half-full part]
+  (cond
+    (< (::record/count part) half-full)
+      [nil (tablet/from-records (read-all store part nil))]
+
+    (< limit (::record/count part))
+      [(partition-records store params (read-all store part nil)) nil]
+
+    :else
+      [[part] nil]))
+
+
 (defn- apply-patch
   "Performs an update on the tablet by applying the patch changes. Returns an
   updated tablet, or nil if the result was empty."
@@ -272,9 +289,8 @@
     (< (count (tablet/read-all pending)) half-full)
       (if-let [prev (peek result)]
         ; Load last result link and redistribute into two valid partitions.
-        (->> pending
-             (tablet/join (tablet/from-records (read-all store prev nil)))
-             (tablet/read-all)
+        (->> (tablet/read-all pending)
+             (concat (read-all store prev nil))
              (partition-records store params)
              (into (pop result)))
         ; No siblings, so return virtual tablet for carrying.
@@ -311,9 +327,9 @@
         (let [[part changes] (first inputs)]
           (if (and (nil? pending) (empty? changes))
             ; No pending records or changes, so use "pass through" logic.
-            ; FIXME: this will allow invalid partitions if the partition limit has changed!
-            ; TODO: check partition validity, redistribute if needed
-            (recur (conj result part) nil (next inputs))
+            (let [[parts pending] (check-partition store params limit half-full part)]
+              (recur (into result parts) pending (next inputs)))
+
             ; Load partition data or use virtual tablet records.
             (let [tablet (tablet/from-records (read-all store part nil))
                   tablet' (tablet/join pending (apply-patch tablet changes))]
@@ -325,13 +341,13 @@
                 ; Original partition data was unchanged by updates.
                 (= tablet tablet')
                   ; Original linked partition remains unchanged by update.
-                  ; FIXME: this will allow invalid partitions if the partition limit has changed!
-                  (recur (conj result part) nil (next inputs))
+                  (let [[parts pending] (check-partition store params limit half-full part)]
+                    (recur (into result parts) pending (next inputs)))

                 ; Accumulated enough records to output full partitions.
                 (<= (+ limit half-full) (count (tablet/read-all tablet')))
-                  (let [[parts pending'] (emit-parts store params emit-threshold emit-size tablet')]
-                    (recur (into result parts) pending' (next inputs)))
+                  (let [[parts pending] (emit-parts store params emit-threshold emit-size tablet')]
+                    (recur (into result parts) pending (next inputs)))

                 ; Not enough data to output a partition yet, keep pending.
                 :else


Initialize compiler state with opts

Initialize compiler state with opts

--- src/adzerk/boot_cljs/impl.clj
+++ src/adzerk/boot_cljs/impl.clj
@@ -6,7 +6,8 @@
             [clojure.string :as str]
             [clojure.edn :as edn]
             [cljs.analyzer :as ana]
-            [cljs.analyzer.api :as ana-api :refer [empty-state warning-enabled?]]
+            [cljs.env :as env]
+            [cljs.analyzer.api :as ana-api :refer [warning-enabled?]]
             [cljs.build.api :as build-api :refer [build inputs target-file-for-cljs-ns]]
             [clojure.java.io :as io]
             [adzerk.boot-cljs.util :as util]
@@ -14,7 +15,7 @@

 ; Because this ns is loaded in pod, it's private to one cljs task.
 ; Compiler env is a atom.
-(def ^:private stored-env (empty-state))
+(def ^:private stored-env (atom nil))

 (defn ns-dependencies
   "Given a namespace as a symbol return list of namespaces required by the namespace."
@@ -147,13 +148,15 @@
                                          "\n"))
                         (butil/dbug* "%s\n" (butil/pp-str warning-data))
                         (swap! warnings conj warning-data)))))]
+    ;; ana-api/empty-state doesn't take options, so need to use this instead
+    (swap! stored-env #(or % (env/default-compiler-env opts)))
     (try
       (build
         (inputs input-path)
         (assoc opts :warning-handlers [handler])
-        stored-env)
+        @stored-env)
       {:warnings  @warnings
-       :dep-order (dep-order stored-env opts)}
+       :dep-order (dep-order @stored-env opts)}
       (catch Exception e
         {:exception (util/serialize-object (handle-ex e source-paths dirs))}))))

@@ -171,12 +174,13 @@

 (defn backdate-macro-dependants!
   [output-dir changed-files]
-  (doseq [cljs-ns (->> changed-files
-                       (map (comp symbol util/path->ns))
-                       (build-api/cljs-dependents-for-macro-namespaces stored-env))]
-    ; broken
-    ; (build-api/mark-cljs-ns-for-recompile! cljs-ns output-dir)
-    (let [f (build-api/target-file-for-cljs-ns cljs-ns output-dir)]
-      (when (.exists f)
-        (butil/dbug "Backdate macro dependant cljs ns: %s\n" cljs-ns)
-        (.setLastModified f 5000)))))
+  (if @stored-env
+    (doseq [cljs-ns (->> changed-files
+                         (map (comp symbol util/path->ns))
+                         (build-api/cljs-dependents-for-macro-namespaces @stored-env))]
+      ; broken
+      ; (build-api/mark-cljs-ns-for-recompile! cljs-ns output-dir)
+      (let [f (build-api/target-file-for-cljs-ns cljs-ns output-dir)]
+        (when (.exists f)
+          (butil/dbug "Backdate macro dependant cljs ns: %s\n" cljs-ns)
+          (.setLastModified f 5000))))))


Fix require order

Fix require order

--- src/braid/search/core.cljc
+++ src/braid/search/core.cljc
@@ -7,8 +7,8 @@
           [braid.search.server :as search]]
          :cljs
          [[clojure.string :as string]
+          [re-frame.core :refer [dispatch]]
           [spec-tools.data-spec :as ds]
-          [re-frame.core :refer [dispatch]]
           [braid.core.client.routes :as routes]
           [braid.core.client.state.helpers :as helpers :refer [key-by-id]]
           [braid.search.ui.search-page :refer [search-page-view]]


Works in Firefox now

Works in Firefox now

--- src/webapp/client/components/playback.cljs
+++ src/webapp/client/components/playback.cljs
@@ -107,7 +107,7 @@
               (dom/div
                #js {
                     :style      #js {:padding-top "40px"
-                                     :background-color
+                                     :backgroundColor
                                      (if
                                        (= (get-in ui
                                                [:sessions data :highlighted]) "true")


Improve sequence shrinking

Improve sequence shrinking

Consider all elements in a sequence for removal when shrinking a
sequence. Previously, we only considered remove the first or last
element, in addition to shrinking the individual elements of the
sequence.

--- src/simple_check/generators.clj
+++ src/simple_check/generators.clj
@@ -23,6 +23,16 @@
           (return-fn [])
           ms))

+(defn- exclude-nth
+  [n coll]
+  "Exclude the nth value in a collection."
+  (lazy-seq
+    (when-let [s (seq coll)]
+      (if (zero? n)
+        (rest coll)
+        (cons (first s)
+              (exclude-nth (dec n) (rest s)))))))
+
 ;; Rose tree
 ;; ---------------------------------------------------------------------------
 ;;
@@ -99,8 +109,7 @@
   {:no-doc true}
   [roses]
   (concat
-    [(rest roses)]
-    [(drop-last roses)]
+    (map-indexed (fn [index _] (exclude-nth index roses)) roses)
     (rose-permutations (vec roses))))

 (defn shrink-rose


Note and remove unneeded argument

Note and remove unneeded argument

--- src/simple_check/generators.clj
+++ src/simple_check/generators.clj
@@ -1,6 +1,9 @@
 (ns simple-check.generators
   (:import java.util.Random)
   (:refer-clojure :exclude [int vector list map keyword char boolean]))
+
+
+;; TODO: namespace the :gen tag

 ;; Helpers
 ;; ---------------------------------------------------------------------------
@@ -148,7 +151,7 @@

 (defn int-gen
   ([rand-seed size]
-   (call-gen (choose (- 0 size) size)
+   (call-gen (choose (- size) size)
       rand-seed size)))

 (def int [:gen int-gen])


define the variable serve-html5-app

define the variable serve-html5-app

--- src/bitfondue/handler.clj
+++ src/bitfondue/handler.clj
@@ -69,6 +69,8 @@
                                             :img      v/required
                                             :tab_info v/required
                                             :html     v/required))
+(def serve-html5-app
+  (slurp "resources/public/index.html"))

 (defroutes app-routes
   (GET "/dashboard" [] home)


This is arguable, but for simple datastructures I find it clearer to just manipulate them in place

--- src/overcode/introvert.cljs
+++ src/overcode/introvert.cljs
@@ -23,15 +23,6 @@
     (.push arr v))
   arr)

-(defn visit!
-  "Marks potentially linked objects as visited to handle circular refs."
-  ([visited obj out]
-   (swap! visited assoc obj out)
-   out)
-
-  ([visited obj] (visit! visited obj "Circular Ref")))
-
-
 ;;***************************************************************************
 ;; ->js
 ;;***************************************************************************
@@ -46,7 +37,7 @@
        "Circular Seq"
        was-visited)
      (let [out (array)]
-       (visit! visited obj out)
+       (swap! visited assoc obj out)
        (array-append out (map #(->js % flat visited) obj)))))

   ([obj flat] (seq->js obj flat (atom {})))
@@ -60,7 +51,7 @@
        "Circular Map"
        was-visited)
      (let [out (js-obj)]
-       (visit! visited obj out)
+       (swap! visited assoc obj out)
        (dorun
         (map
          #(let [key (->js (first %)  flat visited)
@@ -80,7 +71,7 @@
        "Circular NS"
        was-visited)
      (let [out (js-obj)]
-       (visit! visited obj out)
+       (swap! visited assoc obj out)
        (dorun
         (map
          #(let [key %


Fix menu active status

Fix menu active status

--- src/popup/ygq/popup/ui.cljs
+++ src/popup/ygq/popup/ui.cljs
@@ -230,6 +230,8 @@

 (def category-group (om/factory CategoryGroup))

+(declare Root)
+
 (om/defui ^:once MainViewLink
   static css/CSS
   (local-rules [_] [[:.item {:background     "antiquewhite"
@@ -243,17 +245,27 @@
                     [:.active {:background "#ffce8c"}]])
   (include-children [_] [])

+  static om/IQuery
+  (query [_] [:ui/main-view])
+
   Object
   (render [this]
     (let [{:ui/keys [main-view label component]} (om/props this)
-          {:keys [item active]} (css/get-classnames MainViewLink)]
-      (dom/a #js {:className (cond-> item
+          {:keys [menu-item menu-item-active]} (css/get-classnames Root)]
+      (dom/a #js {:className (cond-> menu-item
                                (= (-> (om/props component) :ui/main-view) main-view)
-                               (str " " active))
+                               (str " " menu-item-active))
                   :onClick   (pd #(om/transact! component `[(ui/set-main-view {:view ~main-view}) :ui/main-view]))}
         label))))

-(def main-view-link (om/factory MainViewLink))
+(defn main-view-link [{:ui/keys [main-view label component]}]
+  (let [{:keys [menu-item menu-item-active]} (css/get-classnames Root)]
+    (dom/a #js {:className (cond-> menu-item
+                             (= (-> (om/props component) :ui/main-view) main-view)
+                             (str " " menu-item-active))
+                :onClick   (pd #(do
+                                  (om/transact! component `[(ui/set-main-view {:view ~main-view}) :ui/main-view])))}
+      label)))

 (om/defui ^:once Root
   static uc/InitialAppState
@@ -284,7 +296,17 @@
                       :outline         "none"
                       :text-decoration "none"}]

-                    [:.video-chooser {:display "flex"}]])
+                    [:.video-chooser {:display "flex"}]
+
+                    [:.menu-item {:background     "antiquewhite"
+                                  :color          "#000"
+                                  :cursor         "pointer"
+                                  :flex           "1"
+                                  :text-align     "center"
+                                  :padding        "8px"
+                                  :font-weight    "bold"
+                                  :text-transform "uppercase"}]
+                    [:.menu-item-active {:background "#ffce8c"}]])
   (include-children [_] [MainViewLink
                          QueuedVideo
                          CategoryGroup])


Tweak dragging to same square

Tweak dragging to same square

--- src/chessground/ctrl.cljs
+++ src/chessground/ctrl.cljs
@@ -61,7 +61,7 @@
     (if (= orig dest)
       ; dragging to same square: replace piece to origin
       (let [new-state (-> state (assoc :dragging false))]
-        [new-state (fn [root chans] (show/move root orig dest))])
+        [new-state (fn [root chans] (show/un-move root orig))])
       ; moving to a non allowed square:
       (if (and (not (:dragging state)) (data/is-movable? state dest))
         ; when not dragging, allow to reselect movable pieces with a single click/touch


fix absence of callback

fix absence of callback

--- src/chessground/ctrl.cljs
+++ src/chessground/ctrl.cljs
@@ -24,9 +24,9 @@
   (dissoc
     (or (when (data/can-move state orig dest)
           (when-let [new-chess (chess/move-piece (:chess state) orig dest)]
-            (let [new-state (assoc state :chess new-chess)
-                  callback (-> state :movable :events :after)]
-              (callback (clj->js orig) (clj->js dest))
+            (let [new-state (assoc state :chess new-chess)]
+              (when-let [callback (-> state :movable :events :after)]
+                (callback (clj->js orig) (clj->js dest)))
               new-state)))
         state)
     :selected))


don't update *cljs-gen-col* unless it's bound to a value

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -112,7 +112,7 @@
      (seq? x) (apply emits x)
      (fn? x)  (x)
      :else (let [s (print-str x)]
-             (when *cljs-source-map*
+             (when *cljs-gen-col*
                (swap! *cljs-gen-col* (fn [col] (+ col (count s)))))
              (print s))))
   nil)


Remove warning "(. obj foo) is no longer a property access"

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -963,9 +963,6 @@
 ;; (. o m)
 (defmethod build-dot-form [::expr ::symbol ()]
   [[target meth args]]
-  (debug-prn "WARNING: The form " (list '. target meth)
-             " is no longer a property access. Maybe you meant "
-             (list '. target (symbol (str '- meth))) " instead?")
   (build-method-call target meth args))

 ;; (. o (m))


revert cljs.closure/compile-file "optimization", must always populate
compilation environment with analysis information, not doing so
damages composition of namespaces with smaller compilation units like
expressions. the problem was uncovered by starting REPLs with cached
files, the second run would be borked because we compiled core but did
not populate the compilation environment.

Include comment covering this point as well.

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -1125,7 +1125,13 @@
                           {:recompile (into recompile (ana/ns-dependents ns))
                            :visited   (conj visited ns)})))
                     ret))
-                ns-info))
+                (do
+                  ;; always populate compilation environment with analysis information
+                  ;; while it would seem this isn't necessary avoiding to do so damages
+                  ;; composition of smaller compilation units like expressions (i.e. REPLs)
+                  (when-not (contains? (::ana/namespaces @env/*compiler*) ns)
+                    (with-core-cljs opts (fn [] (ana/analyze-file src-file opts))))
+                  ns-info)))
             (catch Exception e
               (throw (ex-info (str "failed compiling file:" src) {:file src} e))))
           (throw (java.io.FileNotFoundException. (str "The file " src " does not exist."))))))))


Refactor.

Refactor.

--- src/clj/freefrog/lang.clj
+++ src/clj/freefrog/lang.clj
@@ -19,11 +19,10 @@

 (ns freefrog.lang
   (:require [clj-yaml.core :as yaml]
-            [clojure.pprint :as pp]
             [clojure.walk :as walk]
             [freefrog.governance :as g]))

-(defn create-anchor-circle [{:keys [name cross-links]}]
+(defn create-anchor-circle [_ {:keys [name cross-links]}]
   (let [anchor-circle (g/create-circle name)]
     (reduce g/add-role-to-circle
             anchor-circle
@@ -40,24 +39,17 @@
             "Create Role"          create-role
             "Create Circle"        create-circle})

-(defn process-command
-  ([[command args]]
-   (let [fn-to-call (get verbs command)]
-     (fn-to-call (walk/keywordize-keys args))))
-  ([circle [command args]]
-   (try
-     (let [fn-to-call (get verbs command)]
-       (fn-to-call circle (walk/keywordize-keys args)))
-     (catch Exception e
-       (printf "Unable to process command %s / %s%n" command args)
-       (throw e)))))
+(defn process-command [circle [command args]]
+  (try
+    (let [fn-to-call (get verbs command)]
+      (fn-to-call circle (walk/keywordize-keys args)))
+    (catch Exception e
+      (printf "Unable to process command %s / %s%n" command args)
+      (throw e))))

 (defn execute-governance
   ([governance-string]
-   (let [parsed-document (-> governance-string
-                             (yaml/parse-string)
-                             (walk/stringify-keys))]
-     (process-command (first parsed-document))))
+   (execute-governance nil governance-string))
   ([circle governance-string]
    (let [parsed-document (-> governance-string
                              (yaml/parse-string)


Use Long instead of Integer, because Clojure defaults to that.

--- src/clj/guangyin/core.clj
+++ src/clj/guangyin/core.clj
@@ -193,7 +193,7 @@
   java.lang.String
   (local-date ([this] (wrap (LocalDate/parse this)))
               ([this param] (wrap (LocalDate/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (local-date [year month day] (wrap (LocalDate/of year month day))))

 (defn local-time?
@@ -249,7 +249,7 @@
   java.lang.String
   (local-time ([this] (wrap (LocalTime/parse this)))
               ([this param] (wrap (LocalTime/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (local-time ([hour minute] (wrap (LocalTime/of hour minute)))
               ([hour minute second] (wrap (LocalTime/of hour minute second)))
               ([hour minute second nanosecond]
@@ -310,7 +310,7 @@
   java.lang.String
   (offset-time ([this] (wrap (OffsetTime/parse this)))
                ([this param] (wrap (OffsetTime/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (offset-time ([hour minute second nanosecond offset]
                 (wrap (OffsetTime/of hour minute second nanosecond offset)))))

@@ -346,7 +346,7 @@
   (local-date-time ([this] (wrap (LocalDateTime/parse this)))
                    ([this param]
                     (wrap (LocalDateTime/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (local-date-time ([year month day hour minute]
                     (wrap (LocalDateTime/of year month day hour minute)))
                    ([year month day hour minute second]
@@ -391,7 +391,7 @@
   (offset-date-time ([this] (wrap (OffsetDateTime/parse this)))
                     ([this param]
                      (wrap (OffsetDateTime/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (offset-date-time ([year month day hour minute second nanosecond offset]
                      (wrap (OffsetDateTime/of year month day hour minute second
                                               nanosecond
@@ -432,7 +432,7 @@
   (zoned-date-time ([this] (wrap (ZonedDateTime/parse this)))
                    ([this param]
                     (wrap (ZonedDateTime/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (zoned-date-time ([year month day hour minute second nanosecond zone]
                      (wrap (ZonedDateTime/of year month day hour minute second
                                               nanosecond @(zone-id zone))))))
@@ -461,7 +461,7 @@
   java.lang.String
   (year ([this] (wrap (Year/parse this)))
         ([this param] (wrap (Year/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (year [this] (Year/of this)))

 (defn year-month?
@@ -486,7 +486,7 @@
   java.lang.String
   (year-month ([this] (wrap (YearMonth/parse this)))
               ([this param] (wrap (YearMonth/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (year-month [year month] (YearMonth/of year month)))

 (defn month?
@@ -515,7 +515,7 @@
   (month [this] (wrap (Month/from (LocalDate/now this))))
   java.time.ZoneId
   (month [this] (wrap (Month/from (LocalDate/now this))))
-  java.lang.Integer
+  java.lang.Long
   (month [this] (Month/of this)))

 (defn month-day?
@@ -543,7 +543,7 @@
   java.lang.String
   (month-day ([this] (wrap (MonthDay/parse this)))
              ([this param] (wrap (MonthDay/parse this (unwrap param)))))
-  java.lang.Integer
+  java.lang.Long
   (month-day [month day] (MonthDay/of month day)))

 (defn day-of-week?
@@ -572,7 +572,7 @@
   (day-of-week [this] (wrap (DayOfWeek/from (LocalDate/now this))))
   java.time.ZoneId
   (day-of-week [this] (wrap (DayOfWeek/from (LocalDate/now this))))
-  java.lang.Integer
+  java.lang.Long
   (day-of-week [this] (DayOfWeek/of this)))

 (defn zone-id?
@@ -652,7 +652,7 @@
   (zone-offset [this] (wrap (ZoneOffset/from this)))
   java.lang.String
   (zone-offset [this] (wrap (ZoneOffset/of this)))
-  java.lang.Integer
+  java.lang.Long
   (zone-offset ([this] (wrap (ZoneOffset/ofHours this)))
                ([hours minutes]
                 (wrap (ZoneOffset/ofHoursMinutes hours minutes)))))


allow just sending tags, with no id/timestamp

--- src/clj/tictag/server.clj
+++ src/clj/tictag/server.clj
@@ -41,7 +41,6 @@
                                  (:local-time (first pings))
                                  (:local-time (last pings)))))

-
       ;; lookup by id
       (db/pending-timestamp db cmd)
       (let [id        cmd
@@ -56,7 +55,18 @@
       (db/is-ping? db (Long. cmd))
       (let [long-time (Long. cmd)
             tags      args]
-        (db/add-tags db long-time tags (utils/local-time-from-long long-time))))))
+        (db/add-tags db long-time tags (utils/local-time-from-long long-time)))
+
+      :else
+      (let [tags      args
+            last-ping (db/get-pings (:db db) ["select * from pings order by timestamp desc limit 1"])]
+        (db/update-tags! db [(assoc last-ping :tags args)])
+        (twilio/response
+         (format
+          "<Response><Message>Updated ping with timestamp %s, old pings: %s, new pings: %s</Message></Response>"
+          (:timestamp last-ping)
+          (pr-str (:tags last-pings))
+          (pr-str (set args))))))))

 (def sms
   (POST "/sms" [Body :as {db :db :as req}]


Refactor search-input matching

Refactor search-input matching

--- src/cljs/kulive/core.cljs
+++ src/cljs/kulive/core.cljs
@@ -61,16 +61,18 @@

 (defn matches-query?
   [search-input class]
-  (if (= "" search-input)
-    true
-    (boolean
-     (or (re-find (re-pattern search-input) (s/lower-case (:name class)))
-         (re-find (re-pattern search-input) (s/lower-case (:number class)))
-         (re-find (re-pattern search-input) (s/lower-case (:time class)))
-         (re-find (re-pattern search-input) (s/lower-case (:credits class)))
-         (re-find (re-pattern search-input) (s/lower-case (:name class)))
-         (re-find (re-pattern search-input) (s/lower-case (:type class)))
-         ))))
+  (let [lc s/lower-case
+        match-input-to-key (fn [key] (re-find (re-pattern (lc search-input))
+                                              (lc (key class))))]
+    (if (= "" search-input)
+      true
+      (boolean (or (match-input-to-key :name)
+                   (match-input-to-key :number)
+                   (match-input-to-key :time)
+                   (match-input-to-key :credits)
+                   (match-input-to-key :name)
+                   (match-input-to-key :type)
+                   )))))

 (defn classes-component
   []


Add support of :mouse-wheel option for quil.core/sketch for ClojureScript version.

--- src/cljs/quil/sketch.cljs
+++ src/cljs/quil/sketch.cljs
@@ -51,7 +51,8 @@
         mouse-pressed   (or (:mouse-pressed opts) no-fn)
         mouse-released  (or (:mouse-released opts) no-fn)
         mouse-out       (or (:mouse-exited opts) no-fn)
-        mouse-over      (or (:mouse-entered opts) no-fn)]
+        mouse-over      (or (:mouse-entered opts) no-fn)
+        mouse-scrolled  (or (:mouse-wheel opts) (fn [x] ))]
     (fn [prc]
       (bind-handlers prc
                      :setup  (do
@@ -69,7 +70,8 @@
                      :mousePressed mouse-pressed
                      :mouseReleased mouse-released
                      :mouseOut mouse-out
-                     :mouseOver mouse-over)
+                     :mouseOver mouse-over
+                     :mouseScrolled (apply mouse-scrolled [(* -1 (.-mouseScroll prc))])) ;; -1 need for compability to Clojure version
       (set! (.-quil prc) (atom nil)))))


Dear god when will these packet types end?

--- src/clojurecraft/core.clj
+++ src/clojurecraft/core.clj
@@ -361,6 +361,13 @@
   (-write-byte conn itemcount)
   (-write-short conn itemuses))

+(defn write-packet-transaction [conn {windowid :windowid actionnumber :actionnumber accepted :accepted}]
+  (-write-byte conn (:transaction packet-ids))
+
+  (-write-byte conn windowid)
+  (-write-short conn actionnumber)
+  (-write-bool conn accepted))
+

 ; Writing Wrappers -----------------------------------------------------------------
 (defn flushc [conn]
@@ -397,6 +404,7 @@
     :openwindow           (write-packet-openwindow conn payload)
     :closewindow          (write-packet-closewindow conn payload)
     :windowclick          (write-packet-windowclick conn payload)
+    :transaction          (write-packet-transaction conn payload)

     )
   (flushc conn))
@@ -773,6 +781,40 @@
 (defn read-packet-closewindow [conn]
   (assoc {}
     :windowid (-read-byte conn)))
+
+(defn read-packet-setslot [conn]
+  (assoc {}
+    :windowid (-read-byte conn)
+    :slot (-read-short conn)
+    :itemid (-read-short conn)
+    :itemcount (-read-byte conn)
+    :itemuses (-read-short conn)))
+
+(defn read-packet-windowitems [conn]
+  (letfn [(-read-payload-item []
+             (let [payload (assoc :itemid (-read-short conn))]
+               (if (= (:itemid payload) -1)
+                 payload
+                 (assoc payload
+                        :count (-read-byte conn)
+                        :uses (-read-short conn)))))]
+    (let [prepayload (assoc {}
+                            :windowid (-read-byte conn)
+                            :count (-read-short conn))
+          payload (repeatedly (:count prepayload) -read-payload-item)]
+      (assoc prepayload :payload payload))))
+
+(defn read-packet-updateprogressbar [conn]
+  (assoc {}
+    :windowid (-read-byte conn)
+    :progressbar (-read-short conn)
+    :value (-read-short conn)))
+
+(defn read-packet-transaction [conn]
+  (assoc {}
+    :windowid (-read-byte conn)
+    :actionnumber (-read-short conn)
+    :accepted (-read-short conn)))

 ; Reading Wrappers -----------------------------------------------------------------
@@ -827,6 +869,10 @@
         :thunderbolt               (read-packet-thunderbolt conn)
         :openwindow                (read-packet-openwindow conn)
         :closewindow               (read-packet-closewindow conn)
+        :setslot                   (read-packet-setslot conn)
+        :windowitems               (read-packet-windowitems conn)
+        :updateprogressbar         (read-packet-updateprogressbar conn)
+        :transaction               (read-packet-transaction conn)

         :else (str "UNKNOWN PACKET TYPE: " packet-id)
         ))


Whitespace.

Whitespace.

--- src/clojurecraft/core.clj
+++ src/clojurecraft/core.clj
@@ -61,7 +61,7 @@
                                 :y 85.0, :stance 60.0, :x -120.0}})
         world (ref {})
         bot {:connection conn, :outqueue outqueue, :player player, :world world,
-             :packet-counts-in (atom {}), :packet-counts-out(atom {})}]
+             :packet-counts-in (atom {}), :packet-counts-out (atom {})}]

     (println "connecting")
     (login bot)
@@ -88,8 +88,8 @@

 ; Scratch --------------------------------------------------------------------------
-(def bot (connect minecraft-local))
-(act/move bot 0 4 0)
+;(def bot (connect minecraft-local))
+;(act/move bot 4 0 2)
 ;(pprint @(:packet-counts-in bot))
 ;(pprint @(:packet-counts-out bot))
 ;(pprint (:player bot))


Change totp code form

Change totp code form

--- src/cylon/impl/oauth2.clj
+++ src/cylon/impl/oauth2.clj
@@ -185,13 +185,16 @@
                [:h1 "Please can I have your auth code"]

                (let [secret (get-session-value req "session-id" (:session-store this) :totp-secret)]
-                 [:p "Secret is " secret]
-                 [:p "Hint, Type this: " (totp-token secret)])
-
-               [:form {:method :post
-                       :action (path-for (:modular.bidi/routes req)
-                                         ::post-totp-code)}
-                [:input {:type "text" :id "code" :name "code"}]])})
+                 [:div
+
+
+                  [:form {:method :post
+                          :action (path-for (:modular.bidi/routes req)
+                                            ::post-totp-code)}
+                   [:input {:type "text" :id "code" :name "code"}]
+                   [:input {:type "submit"}]]
+
+                  [:p "(Hint, maybe it's something like... this ? " (totp-token secret) ")"]]))})

      ::post-totp-code
      (-> (fn [req]


Add missing closing bracket to sample code

--- src/re_demo/introduction.cljs
+++ src/re_demo/introduction.cljs
@@ -163,7 +163,7 @@
              [h-box
               :height \"100px\"
               :children [[box :size \"70px\" :child \"Nav\"]
-                         [box :size \"1\" :child \"Content\"]]
+                         [box :size \"1\" :child \"Content\"]]]
              [box :child \"Footer\"]]]"]]]
                           [box
                            :size "100px"


Rename span view to string view

Rename span view to string view

--- src/reabledit/components.cljs
+++ src/reabledit/components.cljs
@@ -7,7 +7,7 @@
 ;; Cell views
 ;;

-(defn span-view
+(defn string-view
   []
   (fn [v _]
     [:span v]))
@@ -124,7 +124,7 @@
           (get-in @state path)
           #(swap! state assoc-in path %)
           move-to-cell!])
-       (let [view (or (:view column) (span-view))]
+       (let [view (or (:view column) (string-view))]
          [view (get row-data (:key column)) enable-edit!]))]))

 (defn data-table-row


Minor refactor

Minor refactor

--- src/cljs/db_quiz/core.cljs
+++ src/cljs/db_quiz/core.cljs
@@ -58,19 +58,19 @@
                         :normal 3750
                         :hard 8750)
                   (rand-int 2500))
-        chosen-classes (class-selection classes)]
-    (go (let [results (map model/despoilerify
-                           (<! (model/sparql-query endpoint
-                                                   "sparql/cs_dbpedia.mustache"
-                                                   :data {:classes chosen-classes
-                                                          :limit limit
-                                                          :offset offset})))]
-          (swap! app-state (fn [state]
-                             (assoc state
-                                    :board
-                                    (into {} (map (fn [[k v] result] [k (merge v result)])
-                                                  board
-                                                  results)))))))))
+        chosen-classes (class-selection classes)
+        query-channel (model/sparql-query endpoint
+                                          "sparql/cs_dbpedia.mustache"
+                                          :data {:classes chosen-classes
+                                                 :limit limit
+                                                 :offset offset})
+        merge-board-with-data (fn [board data]
+                                (into {}
+                                      (map (fn [[k v] result] [k (merge v result)])
+                                           board
+                                           data)))]
+    (go (let [results (map model/despoilerify (<! query-channel))]
+          (swap! app-state #(assoc % :board (merge-board-with-data board results)))))))

 (defn load-gdocs-items
   ; Testing data:


Minor cleanup

Minor cleanup

--- src/cljs/nansi/mirror.cljs
+++ src/cljs/nansi/mirror.cljs
@@ -16,19 +16,16 @@

 (defn replace-char
   [file]
-  (let [ascii (s/split-lines file)]
-    (reduce
-     (fn [acc line]
-       (let [r (apply str (reverse line))
-             c (s/replace r regex #(get pairs %))]
-         (conj acc c)))
-     '()
-     ascii)))
+  (let [lines (s/split-lines file)]
+    (reverse
+     (reduce
+      (fn [acc line]
+        (let [r (apply str (reverse line))
+              c (s/replace r regex #(get pairs %))]
+          (conj acc c)))
+      '()
+      lines))))

-(def lines (reverse (replace-char)))
-(def longest-length (-> (sort-by count lines)
-                        last
-                        count))
 (defn get-padding
   [lines]
   (let [longest-length (-> (sort-by count lines)
@@ -48,7 +45,7 @@

 (defn output
   [ch]
-  (go (let [lines (reverse (replace-char (<! ch)))]
+  (go (let [lines (replace-char (<! ch))]
         (doseq [l (join-line-padding lines)]
           (println l))))
   )


add var parsing

add var parsing

--- src/cljs_api_gen/parse.clj
+++ src/cljs_api_gen/parse.clj
@@ -104,6 +104,15 @@
      :signature signatures
      :type "function"}))

+(defn parse-var
+  [form]
+  (let [name- (second form)
+        m (meta name-)
+        docstring (fix-docstring (:doc m))
+        dynamic? (:dynamic m)]
+    {:docstring docstring
+     :type (if dynamic? "dynamic var" "var")}))
+
 (defmulti parse-form*
   (fn [form]
     (cond
@@ -115,13 +124,22 @@
            (not (:private (meta (second form)))))
       "defmacro"

-      (and (= 'def (first form))
+      (and (#{'def 'defonce} (first form))
            (list? (nth form 2 nil))
            (= 'fn (first (nth form 2 nil)))
+           (not (:private (meta (second form))))
+           (not (:dynamic (meta (second form)))))
+      "def fn"
+
+      (and (#{'def 'defonce} (first form))
            (not (:private (meta (second form)))))
-      "def fn"
+      "var"

       :else nil)))
+
+(defmethod parse-form* "var"
+  [form]
+  (parse-var form))

 (defmethod parse-form* "def fn"
   [form]


added almorzar cenar

added almorzar cenar

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -30,6 +30,10 @@
              :synsem {:cat :verb
                       :sem {:pred :warn}}}

+   "almorzar" {:espanol {:boot-stem "almuerz"}
+             :synsem {:cat :verb
+                      :sem {:pred :have-lunch}}}
+
    "anunciar" {:synsem {:cat :verb
                         :sem {:pred :announce}}}

@@ -62,6 +66,9 @@

    "cambiar" {:synsem {:cat :verb
                        :sem {:pred :change}}}
+
+   "cenar" {:synsem {:cat :verb
+                       :sem {:pred :have-dinner}}}

    "cerrar" {:espanol {:boot-stem "cierr"}
              :synsem {:cat :verb
@@ -463,6 +470,7 @@
    "poder"
    (let [shared-part-of-poder
                    {:espanol {:boot-stem "pued"}
+                    {:preterito-stem "pud"}
                     :synsem {:cat :verb}}]
      [(merge shared-part-of-poder
              {:synsem {:pred :can}})
@@ -588,7 +596,6 @@
                                  :synsem {:aux false}}}
                        {:synsem {:aux false}})

-              ;; if verb has no :reflexive, then :reflexive is false.
               (if-then {:synsem {:cat :verb
                                  :subcat {:2 {:reflexive false}}}}
                        {:synsem {:subcat {:2 {:reflexive false}}}})


added poner

added poner

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -659,6 +659,18 @@
       (merge shared-part-of-poder
              {:synsem {:pred :be-able-to}})])

+   "poner" {:espanol {:future-stem "pondr"
+                   :present {:1sing "tengo"
+                             :2sing "tienes"
+                             :3sing "tiene"
+                             :1plur "tenemos"
+                             :2plur "tenéis"
+                             :3plur "tienen"}
+                   :preterito-stem "tuv"}
+                             :synsem {:cat :verb
+                  :sem {:subj {:animate true}
+                        :pred :put}}}
+
    "quedarse" (let [subject-semantics (ref {:animate true})
                     subject-agr (ref :top)]
                 {:synsem {:cat :verb


random-nonce! is private now

random-nonce! is private now

--- test/caesium/magicnonce/secretbox_test.clj
+++ test/caesium/magicnonce/secretbox_test.clj
@@ -18,8 +18,8 @@
     (is (u/array-eq (byte-array [1 1 1]) one))))

 (deftest random-nonce!-test
-  (let [a (ms/random-nonce!)
-        b (ms/random-nonce!)]
+  (let [a (#'ms/random-nonce!)
+        b (#'ms/random-nonce!)]
     (is (not (u/array-eq a b)))
     (is (= s/noncebytes (alength ^bytes a) (alength ^bytes b)))))


correct test errors

correct test errors

--- test/clj_money/models/commodities_test.clj
+++ test/clj_money/models/commodities_test.clj
@@ -164,7 +164,7 @@
         commodity (dissoc (attributes context) :exchange)
         result (commodities/create storage-spec commodity)
         commodities (commodities/select-by-entity-id storage-spec entity-id)]
-    (is (= ["Symbol is required"]
+    (is (= ["Exchange is required"]
            (validation/error-messages result :exchange))
         "The result has an error message")
     (is (empty? (->> commodities
@@ -172,36 +172,45 @@
         "The commodity is not retrieved after create")))

 (deftest exchange-must-be-a-valid-exchange
-  (testing "it can be :nyse"
-    (let [context (serialization/realize storage-spec commodity-context)
-        entity-id (-> context :entities first :id)
-        commodity (attributes context)
-        result (commodities/create storage-spec commodity)
-        commodities (commodities/select-by-entity-id storage-spec entity-id)]
-    (is (empty? (validation/error-messages result))
-        "The result has no error messages")))
-  (testing "it can be :nasdaq"
-    (let [context (serialization/realize storage-spec commodity-context)
-        entity-id (-> context :entities first :id)
-        commodity (assoc (attributes context) :exchange :nasdaq)
-        result (commodities/create storage-spec commodity)
-        commodities (commodities/select-by-entity-id storage-spec entity-id)]
-    (is (empty? (validation/error-messages result))
-        "The result has no error messages")))
-  (testing "it can be :fund"
-    (let [context (serialization/realize storage-spec commodity-context)
-        entity-id (-> context :entities first :id)
-        commodity (assoc (attributes context) :exchange :fund)
-        result (commodities/create storage-spec commodity)
-        commodities (commodities/select-by-entity-id storage-spec entity-id)]
-    (is (empty? (validation/error-messages result))
-        "The result has no error messages")))
-  (testing "it cannot be anything other than :nyse, :nasdaq, or :fund"
-    (let [context (serialization/realize storage-spec commodity-context)
-        entity-id (-> context :entities first :id)
-        commodity (assoc (attributes context) :exchange :not-a-valid-exchange)
-        result (commodities/create storage-spec commodity)
-        commodities (commodities/select-by-entity-id storage-spec entity-id)]
-    (is (= ["Exchange must be one of: nasdaq, fund, nyse"]
-           (validation/error-messages result :exchange))
-        "The result has an error messages"))))
+  (let [context (serialization/realize storage-spec commodity-context)]
+    (testing "it can be :nyse"
+      (let [entity-id (-> context :entities first :id)
+            commodity (assoc (attributes context)
+                             :exchange :nyse
+                             :symbol "HD"
+                             :name "Home Depot")
+            result (commodities/create storage-spec commodity)
+            commodities (commodities/select-by-entity-id storage-spec entity-id)]
+        (is (empty? (validation/error-messages result))
+            "The result has no error messages")))
+    (testing "it can be :nasdaq"
+      (let [ entity-id (-> context :entities first :id)
+            commodity (assoc (attributes context)
+                             :exchange :nasdaq
+                             :symbol "APPL"
+                             :name "Apple")
+            result (commodities/create storage-spec commodity)
+            commodities (commodities/select-by-entity-id storage-spec entity-id)]
+        (is (empty? (validation/error-messages result))
+            "The result has no error messages")))
+    (testing "it can be :fund"
+      (let [entity-id (-> context :entities first :id)
+            commodity (assoc (attributes context)
+                             :exchange :fund
+                             :symbol "VFINX"
+                             :name "Vanguard 500 Index")
+            result (commodities/create storage-spec commodity)
+            commodities (commodities/select-by-entity-id storage-spec entity-id)]
+        (is (empty? (validation/error-messages result))
+            "The result has no error messages")))
+    (testing "it cannot be anything other than :nyse, :nasdaq, or :fund"
+      (let [entity-id (-> context :entities first :id)
+            commodity (assoc (attributes context)
+                             :exchange :not-a-valid-exchange
+                             :symbol "NUNYA"
+                             :name "None of your business")
+            result (commodities/create storage-spec commodity)
+            commodities (commodities/select-by-entity-id storage-spec entity-id)]
+        (is (= ["Exchange must be one of: nasdaq, fund, nyse"]
+               (validation/error-messages result :exchange))
+            "The result has an error messages")))))


fix support exception

fix support exception

--- src/synthesis_crawlers/core.clj
+++ src/synthesis_crawlers/core.clj
@@ -240,12 +240,8 @@
                      :all-attrs ::attributes))
 (defn find-container-node
   [node-attrs all-attrs]
-  (println "node-attrs: " node-attrs)
-  (println "all-attrs " all-attrs)
   (set
     (reduce (fn [acc e]
-              (println "find-container-node " (type acc) ": " acc )
-              (println "find-container-node"(type e) ": " e )
               (let [removed (remove #(reach? % e) acc)]
                 (if-not (seq removed)
                   (conj (filter #(not (reach? % e)) acc) e)
@@ -430,13 +426,12 @@
                                                s-extractors)]
         (let [nodes-in-pages (find-nodes-in-page (:pages (sites site)) new-knowledge)
               reachable-attrs (find-reachable-attrs nodes-in-pages)
-              support-nodes (find-support-nodes nodes-in-pages)
+              support-nodes (count-support-nodes (find-support-nodes nodes-in-pages))
               container-cand-nodes (find-container reachable-attrs
                                                    (find-best-attr-set
                                                      nodes-in-pages))
               container-cand-exprs (generate-container-cand-exprs
-                                     container-cand-nodes support-nodes)
-              ]
+                                     container-cand-nodes support-nodes)]
           (println "!!!" container-cand-exprs)
           )))))


Add progress bar for Jenkins sync

Add progress bar for Jenkins sync

--- src/buildviz/jenkins/sync.clj
+++ src/buildviz/jenkins/sync.clj
@@ -3,6 +3,7 @@
             [cheshire.core :as j]
             [clj-http.client :as client]
             [clojure.string :as string]
+            [clj-progress.core :as progress]
             [clojure.tools.logging :as log]))

 (defn add-test-results [jenkins-url {:keys [job-name number] :as build}]
@@ -62,7 +63,10 @@

     (->> (api/get-jobs jenkins-url)
          (mapcat (partial api/get-builds jenkins-url))
+         (progress/init "Syncing")
          (map (partial add-test-results jenkins-url))
          (map jenkins-build->buildviz-build)
          (map (partial put-to-buildviz buildviz-url))
-         doall)))
+         (map progress/tick)
+         dorun
+         (progress/done))))


kvm node conversion

kvm node conversion

--- src/celestial/api/systems.clj
+++ src/celestial/api/systems.clj
@@ -35,6 +35,7 @@
   :aws {:type "Aws" :description "An EC2 based system"}
   :physical {:type "Physical" :description "A physical machine"}
   :openstack {:type "Openstack" :description "An openstack based instance"}
+  :kvm {:type "Kvm" :description "A kvm based instance"}
   :proxmox {:type "Proxmox" :description "A Proxmox based system"}
   :vcenter {:type "Vcenter" :description "A vCenter based system"})

@@ -51,6 +52,7 @@
   :aws {:type "Aws" :description "An EC2 based system"}
   :physical {:type "Physical" :description "A physical machine"}
   :openstack {:type "Openstack" :description "An openstack based instance"}
+  :kvm  {:type "Kvm" :description "A kvm based instance"}
   :proxmox {:type "Proxmox" :description "A Proxmox based system"}
   :vcenter {:type "Vcenter" :description "A vCenter based system"})

@@ -83,6 +85,8 @@

 (defc "/systems" [:proxmox :type] (keyword v))

+(defc "/systems" [:kvm :node] (keyword v))
+
 (defc "/systems" [:machine :os] (keyword v))

 (defc "/systems" [:env] (keyword v))


better classpath conflict handling

better classpath conflict handling

--- src/clj/shadow/cljs/build.clj
+++ src/clj/shadow/cljs/build.clj
@@ -6,29 +6,27 @@
            (java.util.jar JarFile JarEntry)
            (com.google.javascript.jscomp.deps JsFileParser)
            (java.util.logging Level))
-  (:require ;; [clojure.pprint :refer (pprint)]
-    [clojure.data.json :as json]
-    [clojure.java.io :as io]
-    [clojure.set :as set]
-    [clojure.string :as str]
-    [clojure.edn :as edn]
-    [cljs.analyzer :as ana]
-    [cljs.closure :as closure]
-    [cljs.compiler :as comp]
-    [cljs.source-map :as sm]
-    [cljs.env :as env]
-    [cljs.tagged-literals :as tags]
-    [cljs.util :as cljs-util]
-    [clojure.repl :refer (pst)]
-    [clojure.core.reducers :as r]
-    [clojure.tools.reader :as reader]
-    [clojure.tools.reader.reader-types :as readers]
-    [clojure.core.reducers :as r]
-    [loom.graph :as lg]
-    [loom.alg :as la]
-    [cognitect.transit :as transit]
-    [clojure.java.shell :as shell]
-    [shadow.cljs.util :as util]))
+  (:require [clojure.data.json :as json]
+            [clojure.java.io :as io]
+            [clojure.set :as set]
+            [clojure.string :as str]
+            [clojure.edn :as edn]
+            [cljs.analyzer :as ana]
+            [cljs.closure :as closure]
+            [cljs.compiler :as comp]
+            [cljs.source-map :as sm]
+            [cljs.env :as env]
+            [cljs.tagged-literals :as tags]
+            [cljs.util :as cljs-util]
+            [clojure.repl :refer (pst)]
+            [clojure.tools.reader :as reader]
+            [clojure.tools.reader.reader-types :as readers]
+            [loom.graph :as lg]
+            [loom.alg :as la]
+            [cognitect.transit :as transit]
+            [shadow.cljs.util :as util]
+    ;; [clojure.pprint :refer (pprint)]
+            ))

 (defn ^com.google.javascript.jscomp.Compiler make-closure-compiler []
   (com.google.javascript.jscomp.Compiler/setLoggingLevel Level/WARNING)
@@ -422,17 +420,18 @@
   (let [root (io/file path)
         root-path (.getAbsolutePath root)
         root-len (inc (count root-path))]
-    (for [file (file-seq root)
-          :let [abs-path (.getAbsolutePath file)]
-          :when (and (is-cljs-resource? abs-path)
-                     (not (.isHidden file)))
-          :let [name (-> abs-path
-                         (.substring root-len)
-                         (normalize-resource-name))]
-          :when (not (should-ignore-resource? state name))]
-
-      (make-fs-resource state path name file)
-      )))
+    (into [] (for [file (file-seq root)
+                   :let [abs-path (.getAbsolutePath file)]
+                   :when (and (is-cljs-resource? abs-path)
+                              (not (.isHidden file)))
+                   :let [name (-> abs-path
+                                  (.substring root-len)
+                                  (normalize-resource-name))]
+                   :when (not (should-ignore-resource? state name))]
+
+               (make-fs-resource state path name file)
+               ))))
+
 (defn get-resource-for-provide [state ns-sym]
   {:pre [(compiler-state? state)
          (symbol? ns-sym)]}
@@ -684,7 +683,7 @@

 ;; FIXME: must manually bump if anything cache related changes
 ;; use something similar to clojurescript-version
-(def cache-file-version "v2")
+(def cache-file-version "v3")

 (defn get-cache-file-for-rc
   [{:keys [cache-dir] :as state} {:keys [name] :as rc}]
@@ -841,6 +840,8 @@
     (do (log-warning logger (format "ERROR in resource: %s via %s" name url))
         state)

+    ;; no not merge files that don't have the expected path for their ns
+    ;; not really needed but cljs does this, so we should enforce it as well
     (and (= :cljs (:type src))
          (symbol? (:ns src))
          (let [expected-name (ns->cljs-file (:ns src))
@@ -849,8 +850,25 @@
                     (= name expected-cljc)
                     ))))
     (do (log-warning logger (format "ns did not match file-path: %s -> \"%s\" (via \"%s\")" (:ns src) name url))
+        ;; still want to remember the resource so it doesn't get detected as new all the time
+        (assoc-in state [:sources name] src))
+
+    ;; do not merge files that are already present from a different source path
+    (let [existing (get-in state [:sources name])]
+      (and existing
+           (or (not= (:source-path existing)
+                     (:source-path src))
+               (not= (:url existing)
+                     (:url src)))))
+    (do (log-warning logger (format
+                              "duplicate file on classpath \"%s\" (using A)%nA: %s%nB: %s"
+                              name
+                              (get-in state [:sources name :source-path])
+                              (:source-path src)))
         state)

+    ;; now we need to handle conflicts for cljc/cljs files
+    ;; only use cljs if both exist
     :valid-resource
     (let [cljc? (is-cljc? name)
           cljc-name (when (is-cljs? name)
@@ -891,9 +909,10 @@

 (defn merge-resources-in-path
   ([state path]
-    (merge-resources-in-path state path {:reloadable true}))
+   (merge-resources-in-path state path {:reloadable true}))
   ([state path path-opts]
-   (let [file (io/file path)]
+   (let [file (io/file path)
+         resources (do-find-resources-in-path state path)]
      (-> state
          (cond->
            (.isDirectory file)
@@ -902,7 +921,7 @@
                :file file
                :abs-path (.getAbsolutePath file)
                :path path)))
-         (merge-resources (do-find-resources-in-path state path))))))
+         (merge-resources resources)))))

 (defn find-resources
   "finds cljs resources in the given path"
@@ -1817,6 +1836,7 @@
               (log-warning logger
                 (format "MACRO-RELOAD FAILED %s!%n%s" name st)))))
         (assoc-in state [:macros ns] (dissoc rc :scan)))
+
     :delete
     (do (log-progress logger (format "[RELOAD] del: %s" file))
         (unmerge-resource state (:name rc)))
@@ -1897,7 +1917,7 @@
    :macros-loaded #{}
    :use-file-min true

-   :manifest-cache-dir (let [dir (io/file "target" "shadow-build" "jar-manifest" "v1")]
+   :manifest-cache-dir (let [dir (io/file "target" "shadow-build" "jar-manifest" "v2")]
                          (io/make-parents dir)
                          dir)
    :cache-dir (io/file "target" "shadow-build" "cljs-cache")


Fix ranged weapon kills

Fix ranged weapon kills

--- src/cljc/robinson/combat.cljc
+++ src/cljc/robinson/combat.cljc
@@ -506,7 +506,11 @@
                     items)))
               (rc/append-log (gen-attack-message attacker
                                               defender
-                                              attack
+                                              (case attack-type
+                                                :melee attack
+                                                :ranged (get ranged-weapon :id)
+                                                :thrown-item (get thrown-item :id)
+                                                (assert false (format "Unknown attack type %s" (name attack-type))))
                                               defender-body-part
                                               :dead)
                           :white))


Change raft character

Change raft character

--- src/cljc/robinson/render.cljc
+++ src/cljc/robinson/render.cljc
@@ -892,7 +892,7 @@
                                                                  (log/info "raft-cell" out-char cell-items)
                                                                  (if (> (count cell-items) 1)
                                                                    [chr fg (color->rgb :brown)]
-                                                                   ["\u2225" (color->rgb :black) (color->rgb :brown)]))
+                                                                   ["\u01c1" (color->rgb :black) (color->rgb :brown)]))
                                                              :else
                                                                out-char)
                                            shaded-out-char (if (= (get cell :discovered) current-time)


Don't call on-login on dashboard

Don't call on-login on dashboard

--- src/cljs/retroboard/user.cljs
+++ src/cljs/retroboard/user.cljs
@@ -214,7 +214,7 @@
              :onClick create-env}
         title))))

-(defn dashboard-view [app owner {:keys [on-login]}]
+(defn dashboard-view [app owner]
   (reify
     om/IInitState
     (init-state [_]
@@ -225,9 +225,7 @@
         (fetch-boards ch)
         (go (while true
               (let [{:keys [status body]} (<! ch)]
-                (om/set-state! owner :boards body)
-                (if (<= 200 status 300)
-                  (on-login)))))))
+                (om/set-state! owner :boards body))))))
     om/IRenderState
     (render-state [_ {:keys [ch boards status] :as state}]
       (dom/div #js {:id "login-signup"}


Changing reset status code.

Changing reset status code.

--- src/cmr/search/api/routes.clj
+++ src/cmr/search/api/routes.clj
@@ -277,14 +277,14 @@
          (acl/verify-ingest-management-permission
           (acl/add-authentication-to-context request-context params headers))
         (query-svc/clear-cache request-context)
-        {:status 200})
+        {:status 204})

       ;; Clears the cache.
       (POST "/clear-cache" {:keys [request-context params headers]}
         (acl/verify-ingest-management-permission
           (acl/add-authentication-to-context request-context params headers))
         (query-svc/clear-cache request-context)
-        {:status 200}))
+        {:status 204}))
     (route/not-found "Not Found")))

 ;; Copies the body into a new attribute called :body-copy so that after a post of form content type


Ontology additions - skos:member and skos:Collection

--- src/ontologies/grafter/rdf/ontologies/skos.clj
+++ src/ontologies/grafter/rdf/ontologies/skos.clj
@@ -16,3 +16,6 @@
 (def skos:notation (skos "notation"))
 (def skos:altLabel (skos "altLabel"))
 (def skos:note (skos "note"))
+
+(def skos:Collection (skos "Collection"))
+(def skos:member (skos "member"))


Fix debug output

Fix debug output

--- src/puppeteer/infra/client/container_builder.clj
+++ src/puppeteer/infra/client/container_builder.clj
@@ -11,13 +11,15 @@

 (defn create-build
   [{:keys [project-id client] :as comp} build]
-  (println (-> (GoogleCredential/getApplicationDefault)))
-  (-> client
-      .projects
-      .builds
-      (.create project-id build)
-      (.setAccessToken (-> (GoogleCredential/getApplicationDefault) .getAccessToken))
-      .execute))
+  (let [credential (doto (GoogleCredential/getApplicationDefault)
+                     .refreshToken)]
+    (println (-> credential .getAccessToken))
+    (-> client
+        .projects
+        .builds
+        (.create project-id build)
+        (.setAccessToken (-> credential .getAccessToken))
+        .execute)))

 (defrecord ContainerBuilderClientComponent [project-id client]
   component/Lifecycle


fixed emoji once again

fixed emoji once again

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -260,7 +260,7 @@
 (def cool-kid
   [:emoji
    (fn [{:keys [message author time]}]
-     (when (or (re-find #"[\u20a0-\u32ff\ud83c\udc00-\ud83d\udeff\udbb9\udce5-\udbb9\udcee]" message)
+     (when (or (re-find #"[\ud83c\udc00-\ud83d\udeff\udbb9\udce5-\udbb9\udcee]" message)
                (let [candidates (set (re-seq #"\:[\w0-9]+\:" message))]
                  (not-empty (set/intersection candidates emoji/all))))
          {:username author


replace a couple of transact with transact!

--- src-cljs/frontend/sente.cljs
+++ src-cljs/frontend/sente.cljs
@@ -25,10 +25,9 @@
               (put! (get-in @app-state [:comms :controls])
                     [:show-mouse-toggled {:client-uuid client-uuid
                                           :show-mouse? true}])
-              (d/transact (:db @app-state)
-                          ;; hack to prevent loops
-                          (concat layers chats)
-                          {:server-update true}))))
+              (d/transact! (:db @app-state)
+                           (concat layers chats)
+                           {:server-update true}))))

 (defn fetch-subscribers [sente-state app-state document-id]
   (send-msg sente-state [:frontend/fetch-subscribers {:document-id document-id}] 2000
@@ -47,9 +46,9 @@

 (defmethod handle-message :datomic/transaction [app-state message data]
   (let [datoms (:tx-data data)]
-    (d/transact (:db @app-state)
-                (map ds/datom->transaction datoms)
-                {:server-update true})))
+    (d/transact! (:db @app-state)
+                 (map ds/datom->transaction datoms)
+                 {:server-update true})))

 (defmethod handle-message :frontend/subscriber-joined [app-state message data]


PDOK-1259: rename exampe-feature --> bgt-example-feature

--- src/test/clojure/pdok/featured/mustache_test.clj
+++ src/test/clojure/pdok/featured/mustache_test.clj
@@ -29,22 +29,22 @@
                      example-attributes-bgt-wegdeel)
 )

-(defn example-features [n] (repeat n example-feature-bgt-wegdeel))
+(defn example-bgt-features [n] (repeat n example-feature-bgt-wegdeel))

-(defn render-wegdeel-with-example [n]
+(defn render-wegdeel-with-bgt-example [n]
    (map (partial m/render-resource "pdok/featured/templates/bgt-wegdeel.template")
-      (example-features n)))
+      (example-bgt-features n)))

  (deftest test-features-mapping
-   (is (= 5 (count(filter #(re-find #"G0303.0979f33001fd319ae05332a1e90a5e0b" %) (render-wegdeel-with-example 5)))))
-   (is (= 5 (count(filter #(re-find #"<imgeo:inOnderzoek>false</imgeo:inOnderzoek>" %) (render-wegdeel-with-example 5))))))
+   (is (= 5 (count(filter #(re-find #"G0303.0979f33001fd319ae05332a1e90a5e0b" %) (render-wegdeel-with-bgt-example 5)))))
+   (is (= 5 (count(filter #(re-find #"<imgeo:inOnderzoek>false</imgeo:inOnderzoek>" %) (render-wegdeel-with-bgt-example 5))))))

  (deftest test-features-gml-mapping
-   (is (= 5 (count(filter #(re-find #"<gml:posList" %) (render-wegdeel-with-example 5))))))
+   (is (= 5 (count(filter #(re-find #"<gml:posList" %) (render-wegdeel-with-bgt-example 5))))))

  (defn write-gml-files [n]
     (time (with-open [w (clojure.java.io/writer "target/features.gml.json")]
-       (json/generate-stream {:features (render-wegdeel-with-example n)} w))))
+       (json/generate-stream {:features (render-wegdeel-with-bgt-example n)} w))))


fix bad format specification (#1733)

fix bad format specification (#1733)


added note about location of solutions

added note about location of solutions

--- src/tutorial/untangled_tutorial/K_Testing.cljs
+++ src/tutorial/untangled_tutorial/K_Testing.cljs
@@ -89,6 +89,8 @@
   that tests if `2 * 2 = 4`. Remember to update `tests-to-run`. You can use the `ns` preamble from `sample-spec` to
   get the various requires correct.

+  Solutions are in `exercises-solutions-spec`.
+
   ## Assertions

   Special arrows:
@@ -103,6 +105,8 @@

   Create an additonal spec (in the same file as before) that uses the `=fn=>` arrow to check that an expression results
   in an even value.
+
+  Solutions are in `exercises-solutions-spec`.

   ## Mocking

@@ -193,6 +197,8 @@
   **Bonus**: Change your mocking to use =1x=> arrows for `sum-sq` to return different, but predictable, values for
   each call.

+  Solutions are in `exercises-solutions-spec`.
+
   ## Using the original function (Spying)

   If you want to spy on a function, you can use mocking with a pre-capture of the function:
@@ -214,6 +220,8 @@
   but *really* allows the original `sum-sq` to generate the real value. Add assertions that talk about how every result
   is positive, even when the pairs contain negatives. The macro `provided` is the same as `when-mocking`, but allows you
   to add a string to the output (and nest the outline a level deeper) to describe what the mocking is proving.
+
+  Solutions are in `exercises-solutions-spec`.

   ## Timeline testing


Really fix lein profiles...

Really fix lein profiles...

--- lein/.lein/profiles.clj
+++ lein/.lein/profiles.clj
@@ -6,12 +6,11 @@
   :singing {:gpg-key "matthew.russell@wormbase.org"}
   :dependencies [[clojure-ini "0.0.2"]
                  [me.raynes/fs "1.4.6"]]
-  :plugins [
-            [jonase/eastwood "0.2.3"]
+  :plugins [[jonase/eastwood "0.2.3"]
             [lein-ancient "0.6.8"]
             [lein-bikeshed "0.3.0"]
-            [lein-ns-dep-graph "0.1.0-SNAPSHOT"]]
-            [refactor-nrepl "0.2.2"]}
+            [lein-ns-dep-graph "0.1.0-SNAPSHOT"]
+            [refactor-nrepl "0.2.2"]]
  :repl {:dependencies [[acyclic/squiggly-clojure "0.1.6"]
                        [cider/cider-nrepl "0.15.0-SNAPSHOT"]
                        [datomic-schema-grapher "0.0.1"]
@@ -23,4 +22,5 @@
  ;;            "-Dcom.sun.management.jmxremote.ssl=false"
  ;;            "-Dcom.sun.management.jmxremote.authenticate=false"
  ;;            "-Dcom.sun.management.jmxremote.port=43210"]}
- }
+  }}
+


simplify the api service structure

simplify the api service structure

--- src/ephemeris_api/service.clj
+++ src/ephemeris_api/service.clj
@@ -22,25 +22,22 @@
                    :houses false
                    :meta false})})))

-;;(s/with-fn-validation) ;; Optional, but nice to have at compile time
+;; (s/with-fn-validation) ;; Optional, but nice to have at compile time
 (api/defroutes routes
   {:info {:title       "Ephemeris Api"
           :description "For Astrology Applications"
-          :version     "0.1"}
-   :tags [{:name         "ephemeris"
-           :description  "calculate"
-           :externalDocs {:description "Find out more"
-                          :url         "https://github.com/astrolet/ephemeris-api"}}]}
-  [[["/" ^:interceptors [api/error-responses
+          :version     "0.1"
+          :externalDocs {:description "Find out more"
+                         :url         "https://github.com/astrolet/ephemeris-api"}}}
+  [[["/api" ^:interceptors [api/error-responses]
                          (api/negotiate-response)
                          (api/body-params)
                          api/common-body
                          (api/coerce-request)
-                         (api/validate-response)]
-     ["/api" ^:interceptors [(api/doc {:tags ["ephemeris"]})]
-      ["/utc" {:get mundane}]]]
-    ["/swagger.json" {:get api/swagger-json}]
-    ["/*resource" {:get api/swagger-ui}]]])
+                         (api/validate-response)
+      ["/utc" {:get mundane}]
+      ["/swagger.json" {:get api/swagger-json}]
+      ["/*resource" {:get api/swagger-ui}]]]])

 (def service
   {:env :prod


Document grimoire.api.web.read/grim-result

--- src/grimoire/api/web/read.clj
+++ src/grimoire/api/web/read.clj
@@ -36,7 +36,11 @@
   [result]
   (= (:result result) :success))

-(defn grim-result [result]
+(defn grim-result
+  "λ [t] → y
+
+  Helper, destructures out the body of a Grimoire web result."
+  [result]
   (:body result))

 (defn make-request [config thing op]


some formatting

some formatting

--- src/bitsplit_cli/client.cljs
+++ src/bitsplit_cli/client.cljs
@@ -6,7 +6,7 @@
         [bitsplit.storage.protocol :only (all)]
         [bitsplit-cli.constants :only (DIR)]
         [bitsplit-cli.utils :only (call-method callback->channel)])
-    (:require [cljs.core.async :as a])
+    (:require [cljs.core.async :refer (<!) :as a])
     (:use-macros
         [cljs.core.async.macros :only (go)]))

@@ -20,11 +20,11 @@
    "https://blockchain.info/address/$address$?format=json"])

 (defn- balance [result]
-  (or (.-final_balance result)
-      (some-> result
-        .-data
-        .-address
-        .-confirmedBalance)))
+  (or (.-final_balance result) ; blockchain
+      (some-> result ; helloblock
+        (.-data)
+        (.-address)
+        (.-confirmedBalance))))

 (defn- parse-body [response]
   (->> response
@@ -34,18 +34,17 @@
 (defn get-balance [urls address]
   (go
     (if-let [url (-> urls first (.replace "$address$" address))]
-      (let [response (a/<! (request url))]
+      (let [response (<! (request url))]
         (if-let [error (:error response)]
           (do
             (println "zomg error" error)
-            (a/<! (get-balance (rest urls) address)))
+            (<! (get-balance (rest urls) address)))
           (-> response parse-body balance))))))

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

 (defn- send? [fee amount]
     (< (* 3 fee) amount))
@@ -61,12 +60,12 @@
         (-> wallet .-addresses js->clj))
     (unspent-amounts [this]
       (let [my-addrs (addresses this)]
-        (if-not (empty? my-addrs)
+        (if (empty? my-addrs)
+          (go nil)
           (->> my-addrs
             (map (partial address->balance urls))
-            a/merge
-            (a/into { }))
-          (go nil))))
+            (a/merge)
+            (a/into { })))))
     (unspent-channel [this]
       (let [return (a/chan)]
         (js/setInterval


Fix setting content-type when using aleph

When using aleph the :content-type key is not present in the request.

--- src/cider_ci/storage/web.clj
+++ src/cider_ci/storage/web.clj
@@ -64,7 +64,8 @@
   (let [id (java.util.UUID/randomUUID)
         file-path (str (:file_path store) "/" id)
         file (io/file file-path)
-        {content-type :content-type content-length :content-length} request]
+        content-type (-> request :headers (get "content-type"))
+        {content-length :content-length} request]
     (jdbc/with-db-transaction [tx (get-ds)]
       (with-open [in (io/input-stream (:body request))
                   out (io/output-stream file)]


Print explicit "invoked", and "returns" on debug function calls

--- src/cider_ci/utils/debug.clj
+++ src/cider_ci/utils/debug.clj
@@ -21,11 +21,13 @@
   (let [wrapper-fn (fn [f & args]
                      (logging/log (-> target-var meta :ns)
                                   :debug nil
-                                  [(symbol (str (-> target-var meta :name))){:args args}])
+                                  [(symbol (str (-> target-var meta :name)))
+                                   "invoked" {:args args}])
                      (let [res (apply f args)]
                        (logging/log (-> target-var meta :ns)
                                     :debug nil
-                                    [(symbol (str (-> target-var meta :name))){:res res}])
+                                    [(symbol (str (-> target-var meta :name)))
+                                     "returns" {:res res}])
                        res))]
     (hooke/add-hook target-var wrapper-fn)))


Link to source code on GitHub in footer.

--- src/clj/popchange/layout.clj
+++ src/clj/popchange/layout.clj
@@ -89,5 +89,7 @@
            [:a {:href "https://www.liverpool.ac.uk/spatial-demographics/"}
             [:img {:src "/img/csdr_logo.png"}]]]]]]
        [:div.container.text-center
-        [:p.text-muted "University of Liverpool PopChange v1.0 by "
-         [:a {:href "http://www.clearmapping.co.uk/"} "Clear Mapping Co"]]]]])))
+        [:p.text-muted "University of Liverpool PopChange by "
+         [:a {:href "http://www.clearmapping.co.uk/"} "Clear Mapping Co"] ". "
+         "Source code available on "
+         [:a {:href "https://github.com/ClearMappingCo/popchange-web"} "GitHub"] "."]]]])))


allow a format function to be specified with input-field

--- src/clj_money/web/shared.clj
+++ src/clj_money/web/shared.clj
@@ -212,20 +212,21 @@

 (defn- input-field
   "Renders a HTML input field"
-  ([model attribute options]
+  ([model attribute options format-fn]
    [:div.form-group {:class (when (validation/has-error? model attribute)"has-error")}
     (when-not (:suppress-label? options)
       [:label.control-label {:for attribute} (humanize attribute)])
     [:input.form-control (merge options {:id attribute
                                          :name attribute
-                                         :value (get model attribute)})]
+                                         :value (format-fn (get model attribute))})]
     (when (validation/has-error? model)
       (map #(vector :span.help-block %) (validation/get-errors model attribute)))]))

 (defn text-input-field
   ([model attribute] (text-input-field model attribute {}))
-  ([model attribute options]
-   (input-field model attribute (merge options {:type :text}))))
+  ([model attribute options] (text-input-field model attribute options identity))
+  ([model attribute options format-fn]
+   (input-field model attribute (merge options {:type :text}) format-fn)))

 (defn password-input-field
   ([model attribute] (password-input-field model attribute {}))


DBpedia clarification

DBpedia clarification

--- src/cljs/db_quiz/modals.cljs
+++ src/cljs/db_quiz/modals.cljs
@@ -28,8 +28,8 @@
       [:a {:href "https://cs.wikipedia.org/wiki/AZ-kv%C3%ADz"} "AZ-kvíz"]
       ". Jejím cílem je obsadit pole souvisle spojující všechny 3 strany hrací plochy. Hráč získá pole v případě, kdy správně zodpoví položenou otázku. Každá otázka obsahuje popis hádané věci a zkratku jejího názvu. Pokud je otázka pro zvolené pole zodpovězena nesprávně, pole je označeno jako neuhodnuté a jakýkoli hráč na tahu ho může získat bez nutnosti zodpovídání otázky. Na zodpovězení otázky má každý hráč 45 sekund. První hráč, který svými poli souvisle propojí všechny 3 strany hrací plochy, se stává vítězem. Začíná náhodně vylosovaný hráč."]
      [:h2 "Jak hra funguje?"]
-     [:p "V případě DB-quizu jsou herní otázky náhodně generovány na základě databáze. Ve hře je jako databáze použita sémantická podoba české Wikipedia zvaná "
-      [:a {:href "http://cs.dbpedia.org/"} "DBpedia"]
+     [:p "V případě DB-quizu jsou herní otázky náhodně generovány na základě databáze. Ve hře je jako databáze použita sémantická podoba české Wikipedia, která je vytvářena v projektu "
+      [:a {:href "http://dbpedia.org/"} "DBpedia"]
       ". Alternativně lze použít otázky z tabulek v Google Spreadsheets."]
      [:p "Hru dal dohromady "
       [:a {:href "http://mynarz.net/#jindrich"} "Jindřich Mynarz"]


prevent game rendering before game init

prevent game rendering before game init

--- src/cljs/netrunner/game.cljs
+++ src/cljs/netrunner/game.cljs
@@ -14,7 +14,7 @@
          :log []
          :side :corp
          :corp {:user {:username "" :emailhash ""}
-                :identity {:side "Corp"}
+                :identity {}
                 :deck []
                 :hand []
                 :discard []
@@ -26,7 +26,7 @@
                 :agenda-point 0
                 :max-hand-size 5}
          :runner {:user {:username "" :emailhash ""}
-                  :identity {:side "Runner"}
+                  :identity {}
                   :deck []
                   :hand []
                   :discard []
@@ -197,28 +197,29 @@
      (when (> (count (:rfg cursor)) 0)
        (om/build rfg-view (:rfg cursor)))])))

-(defn gameboard [{:keys [side] :as cursor} owner]
+(defn gameboard [{:keys [side gameid] :as cursor} owner]
   (om/component
    (sab/html
     (let [me (if (= side :corp) (:corp cursor) (:runner cursor))
           opponent (if (= side :corp) (:runner cursor) (:corp cursor))]
-      [:div.gameboard
-       [:div.leftpane
-        [:div
-         (om/build stats-view opponent)
-         (om/build scored-view opponent)]
-        [:div
-         (om/build scored-view me)
-         (om/build stats-view me)]]
-
-       [:div.centralpane
-        (om/build zones opponent)
-        (om/build board opponent)
-        (om/build board me)
-        (om/build zones me)]
-
-       [:div.rightpane {}
-        [:div.card-zoom]
-        (om/build log-pane (:log cursor))]]))))
+      (when (> gameid 0)
+        [:div.gameboard
+         [:div.leftpane
+          [:div
+           (om/build stats-view opponent)
+           (om/build scored-view opponent)]
+          [:div
+           (om/build scored-view me)
+           (om/build stats-view me)]]
+
+         [:div.centralpane
+          (om/build zones opponent)
+          (om/build board opponent)
+          (om/build board me)
+          (om/build zones me)]
+
+         [:div.rightpane {}
+          [:div.card-zoom]
+          (om/build log-pane (:log cursor))]])))))

 (om/root gameboard app-state {:target (. js/document (getElementById "gameboard"))})


clean up cache file after finishing

clean up cache file after finishing

--- src/clojure/cljam/sorter.clj
+++ src/clojure/cljam/sorter.clj
@@ -109,6 +109,16 @@
                           blocks))
                       (map-indexed vector blocks-list))))))))))

+(defn clean-split-merge-cache
+  [name-fn sorted-name-fn count]
+  (let [clean (fn [path]
+                (let [f (file path)]
+                  (when (.exists f)
+                    (.delete f))))]
+    (doseq [i (range count)]
+      (clean (name-fn i))
+      (clean (sorted-name-fn i)))))
+
 ;;
 ;; sorter
 ;;
@@ -132,7 +142,8 @@
             (io/write-refs w hdr)
             (io/write-coordinate-blocks w blks))))
       (range num-splited)))
-    (merge-sam wtr hdr sorted-cache-name-fn num-splited)))
+    (merge-sam wtr hdr sorted-cache-name-fn num-splited)
+    (clean-split-merge-cache cache-name-fn sorted-cache-name-fn num-splited)))

 (defn sort-by-qname [rdr wtr]
   (let [alns (sort-alignments-by-qname rdr)


update for error formatting

update for error formatting

--- src/graphql_clj/executor.clj
+++ src/graphql_clj/executor.clj
@@ -14,7 +14,12 @@
   [errors]
   (->> errors
        (map (fn format-error [error]
-              {:message (.getMessage error)}))
+              (let [err (ex-data error)
+                    locations (:locations err)
+                    path (:path err)]
+                (-> {:message (.getMessage error)}
+                    (cond-> locations (assoc :locations locations))
+                    (cond-> path (assoc :path path))))))
        distinct))

 (defn- cleanup-errors


Update to ClojureScript 1.9.88

Update to ClojureScript 1.9.88

--- planck-cljs/project.clj
+++ planck-cljs/project.clj
@@ -1,11 +1,11 @@
 (defproject planck "0.1.0"
   :profiles {:dev
-             {:dependencies [[org.clojure/clojurescript "1.9.76"]
+             {:dependencies [[org.clojure/clojurescript "1.9.88"]
                              [tubular "1.0.0"]]
               :source-paths ["dev"]}
              :build {}}
   :dependencies [[org.clojure/clojure "1.8.0"]
-                 [org.clojure/clojurescript "1.9.76"]       ; comment if building own, and revise planck-cljs/script/build
+                 [org.clojure/clojurescript "1.9.88"]       ; comment if building own, and revise planck-cljs/script/build
                  [org.clojure/tools.reader "1.0.0-beta1"]
                  [tailrecursion/cljson "1.0.7"]
                  [com.cognitect/transit-clj "0.8.285"]


etag handling

etag handling

--- src/statuses/views/main.clj
+++ src/statuses/views/main.clj
@@ -5,7 +5,7 @@
             [clj-time.local :as local])
   (:use [statuses.backend.persistence :only [db get-save-time]]
         [noir.core :only [defpage defpartial render]]
-        [noir.response :only [redirect]]
+        [noir.response :only [redirect set-headers]]
         [noir.request :only [ring-request]]
         [hiccup.element]
         [hiccup.form]
@@ -59,12 +59,16 @@
            (hidden-field "reply-to" id)
            (submit-button "Reply")))

-(defpartial list-page [items next]
-  (common/layout
-   (list [:div (entry-form)]
-         [:div [:ul.updates (map (fn [item] [:li.post (update item)]) items)]]
-         (link-to next "Next"))
-   (nav-links)))
+(defn make-etag [item]
+  (str (:time item)))
+
+(defn list-page [items next]
+  (set-headers {"etag" (make-etag (first items))}
+   (common/layout
+     (list [:div (entry-form)]
+           [:div [:ul.updates (map (fn [item] [:li.post (update item)]) items)]]
+           (link-to next "Next"))
+     (nav-links))))

 (defpartial update-page [item]
   (common/layout
@@ -95,7 +99,13 @@

 (defpage "/statuses/authors/:author" {:keys [author] :as req}
   (let [[query limit offset next] (parse-args req)]
-    (list-page (core/get-latest @db limit offset author) next)))
+    (let [current-etag (make-etag (first (core/get-latest @db 1 offset author)))
+          last-etag (get-in (ring-request) [:headers "if-none-match"])]
+      (println "Current ETag:" current-etag "Last ETag: " last-etag)
+      (if (not= current-etag last-etag)
+        (list-page (core/get-latest @db limit offset author) next)
+        (redirect (:uri (ring-request)) :not-modified)))))
+

 (defpage "/statuses/search" {:as req}
   (let [[query limit offset next] (parse-args req)]


function to get visible area of a "wrap-around" arena

--- src/clj/battlebots/utils.clj
+++ src/clj/battlebots/utils.clj
@@ -29,7 +29,27 @@
         x1 (min- posx radius 0)
         x2 (max+ posx radius x-bound)
         y1 (min- posy radius 0)
-        y2 (min- posy radius y-bound)]
+        y2 (max+ posy radius y-bound)]
+    (map #(subvec % y1 y2) (subvec arena x1 x2))))
+
+(defn get-wrapped-area-in-range
+  "given an arena, a position, and fov radius return an arena subset within range"
+  [arena [posx posy] radius]
+  (let [dims (get-arena-dimensions arena)
+        x-bound (- (get dims 0) 1)
+        y-bound (- (get dims 1) 1)
+        x1 (if (> radius posx)
+             (- posx (mod radius posx))
+             (- posx radius))
+        x2 (if (> (+ posx radius) x-bound)
+             (+ posx (mod (+ posx radius) x-bound))
+             (+ posx radius))
+        y1 (if (> radius posy)
+             (- posy (mod radius posy))
+             (- posy radius))
+        y2 (if (> (+ posy radius) y-bound)
+             (+ posy (mod (+ posy radius)) y-bound)
+             (+ posy radius))]
     (map #(subvec % y1 y2) (subvec arena x1 x2))))

 (defn draw-line
@@ -65,5 +85,5 @@
     res-arena))

 (defn pretty-print-arena
- [arena]
- (doseq [a arena] (println (map :display a))))
+  [arena]
+  (doseq [a (apply map vector arena)] (println (map :display a))))


add INDEXED-VALS navigator

add INDEXED-VALS navigator

--- src/clj/com/rpl/specter.cljc
+++ src/clj/com/rpl/specter.cljc
@@ -993,6 +993,46 @@
                      )))))
       structure
       )))
+
+(defnav
+  ^{:doc "Navigate to [index elem] pairs for each element in a sequence. Changing in index in transforms
+          has same effect as `index-nav`. Indices seen during transform take into account any shifting
+          resulting from prior sequence elements changing indices."}
+  INDEXED-VALS
+  []
+  (select* [this structure next-fn]
+    ;; could be more efficient with a primitve mutable field
+    (let [i (i/mutable-cell -1)]
+      (doseqres NONE [e structure]
+        (i/update-cell! i inc)
+        (next-fn [(i/get-cell i) e])
+        )))
+  (transform* [this structure next-fn]
+    (let [i (i/mutable-cell 0)
+          indices (i/mutable-cell (-> structure count range vec))]
+      (reduce
+       (fn [s e]
+         (let [curri (nth (i/get-cell indices) (i/get-cell i))
+               [newi newe] (next-fn [curri e])]
+           (if (> newi curri)
+             (i/update-cell! indices
+               (fn [ii]
+                 (loop [j (inc curri)
+                        s ii]
+                   (let [news (update s j dec)]
+                     (if (< j newi)
+                       (recur (inc j) news)
+                       news
+                       ))))))
+           (i/update-cell! i inc)
+           (->> s
+                (setval (nthpath curri) newe)
+                (setval (index-nav curri) newi)
+                i/spy
+                )))
+       structure
+       structure
+       ))))

 (defrichnav
   ^{:doc "Navigates to result of running `afn` on the currently navigated value."}


Using clj-time instead of zeller congruent

--- src/journal_creator/core.clj
+++ src/journal_creator/core.clj
@@ -1,5 +1,7 @@
 (ns journal-creator.core
-  (require [clj-time.core :as t]))
+  (require [clj-time.core :as t]
+           [clj-time.local :as l]
+           [clj-time.format :as f]))

 (def days {0 "Saturday"
            1 "Sunday"
@@ -39,7 +41,19 @@
 (defn get-day-of-week [y m d]
   (get days (zeller-congruence y m d) "Unknown"))

+(defn unparse-today [formatter]
+  (f/unparse formatter (t/to-time-zone (t/now) (t/default-time-zone))))
+
+(defn custom-formatter [format] (f/formatter-local format))
+(def get-journal-header (comp #(str "= " %1 " - <SUMMARY GOES HERE> =") unparse-today custom-formatter))
+(def journal-format "MMMM dd, yyyy, EEEE")
+
 (defn -main
   [& args]
-  (println "Today is: " (get-day-of-week 2017 03 01) (calculate-zeller-congruence 2017 03 01))
-  (println (zeller-congruence 2017 02 28)))
+  ; (println "Today is: " (get-today (custom-formatter journal-format)))
+  (println "Today is: " (get-journal-header journal-format))
+  (loop [i (read-line)]
+    (println "row " i)
+    (if (= i "bye")
+      (println "All done!")
+      (recur (read-line)))))