Description column should be displayed before 'class' column

--- src/zg/html_renderer.clj
+++ src/zg/html_renderer.clj
@@ -302,13 +302,13 @@
                                          [:td (:correct search-result)])
                                      [:td (:datetime search-result)]
                                      [:td (user-href (:user search-result) mode)]
+                                     (if (= mode :blacklist)
+                                         [:td (:description search-result)])
                                      [:td (handle-null :class search-result)]
                                      [:td (handle-null :use search-result)]
                                      [:td (handle-null :internal search-result)]
                                      [:td (handle-null :copyright search-result)]
                                      [:td (handle-null :source search-result)]
-                                     (if (= mode :blacklist)
-                                         [:td (:description search-result)])
                                      [:td {:style (if deleted "color:red" "color:green")} (if deleted "deleted" "active")]
                                      [:td (if deleted [:a {:href (str "?undelete=" word) :class "btn btn-default"} "undelete"]
                                                       [:a {:href (str "?delete="   word) :class "btn btn-default"}  "delete"])]


make clojure player more idiomatic

make clojure player more idiomatic

--- src_clj/sample_gamer.clj
+++ src_clj/sample_gamer.clj
@@ -1,28 +1,30 @@
-; An implementation of a sample random gamer in Clojure.
-; -Sam Schreiber
+(ns gamer_namespace
+  (:import [org.ggp.base.player.gamer.statemachine StateMachineGamer]
+           [org.ggp.base.util.statemachine.implementation.prover ProverStateMachine]))

-; NOTE: the implicit 'this symbol is bound to the local class.
+;; An implementation of a sample random gamer in Clojure.
+;; -Sam Schreiber
+(defn SampleClojureGamer []
+  (proxy [StateMachineGamer] []
+    ;; NOTE: the implicit 'this symbol is bound to the local class.

-(ns gamer_namespace)
-
-(defn SampleClojureGamer []
-  (proxy [org.ggp.base.player.gamer.statemachine.StateMachineGamer] []
     (getInitialStateMachine []
-      (new org.ggp.base.util.statemachine.implementation.prover.ProverStateMachine))
+      (ProverStateMachine.))

     (stateMachineSelectMove [timeout]
-      (.
-        (. this (getStateMachine) [])
-        (getRandomMove
-          (. this (getCurrentState) [])
-          (. this (getRole) [])
-        )
-      )
-    )
-
-    (stateMachineMetaGame [timeout] ())
-    (stateMachineAbort [] ())
-    (stateMachineStop [] ())
-    (getName [] ())
-  )
-)+      (let [state-machine (.getStateMachine this)
+            current-state (.getCurrentState this)
+            role          (.getRole this)
+            random-move   (.getRandomMove state-machine
+                                          current-state
+                                          role)]
+        random-move))
+
+    (stateMachineMetaGame [timeout]
+      (println "SampleClojureGamer metagame called"))
+
+    (stateMachineAbort []
+      (println "SampleClojureGamer abort called"))
+
+    (stateMachineStop []
+      (println "SampleClojureGamer stop called"))))


switched fn to macro

switched fn to macro

--- src/datasplash/core.clj
+++ src/datasplash/core.clj
@@ -76,10 +76,10 @@
   [at]
   `(try (deref required-ns) (catch ClassCastException e# (require 'datasplash.core) #{})))

-(defn unwrap-ex-info
+(defmacro unwrap-ex-info
   [e]
-  (let [c (.getCause e)]
-    (if (and c (instance? e UserCodeException) (instance? ExceptionInfo c)) c e)))
+  `(let [c# (.getCause ~e)]
+     (if (and c# (instance? ~e UserCodeException) (instance? ExceptionInfo c#)) c# ~e)))

 (defmacro safe-exec-cfg
   "Like [[safe-exec]], but takes a map as first argument containing the name of the ptransform for better error message"


test to circumvent UserCodeException

test to circumvent UserCodeException

--- src/datasplash/core.clj
+++ src/datasplash/core.clj
@@ -76,6 +76,11 @@
   [at]
   `(try (deref required-ns) (catch ClassCastException e# (require 'datasplash.core) #{})))

+(defn unwrap-ex-info
+  [e]
+  (let [c (.getCause e)]
+    (if (and c (instance? ExceptionInfo c)) c e)))
+
 (defmacro safe-exec-cfg
   "Like [[safe-exec]], but takes a map as first argument containing the name of the ptransform for better error message"
   [config & body]
@@ -91,7 +96,7 @@
                                   (if pt-name# (assoc (ex-data e#) :name pt-name#) (ex-data e#))
                                   (if-let [root# (.getCause e#)] root# e#)))))
        (catch Exception e#
-         (if (instance? ExceptionInfo e#)
+         (if-let [root-exinfo (unwrap-ex-info e#)]
            (throw e#)
            ;; if var is unbound, nothing has been required
            (let [required-at-start# (try-deref required-ns)]


RS & CM - #3 fix merge conflict

RS & CM - #3 fix merge conflict

--- integration/d_cent/integration_test.clj
+++ integration/d_cent/integration_test.clj
@@ -67,11 +67,8 @@
               (fact "cannot post their user profile"
                     (default-app user-profile-post-request)
                     => (contains {:status 401}))
-              (fact "cannot post their email address"
-                    (app email-capture-post-request)
-                    => (contains {:status 401}))
               (fact "can access objective view"
-                    (app objective-view-get-request)
+                    (default-app objective-view-get-request)
                     => (contains {:status 200})
                     (provided
                       (storage/find-by anything anything "some-long-id") => :an-objective))))


Eastwood sees all my flaws

Eastwood sees all my flaws

--- src/grimoire/either.clj
+++ src/grimoire/either.clj
@@ -42,11 +42,12 @@
   [x]
   [:fail x])

-(defn fail? [x]
+(defn fail?
   "λ [t] → Bool

   Type predicate. Matches only two-vectors [:fail x] as documented in
   the fail constructor."
+  [x]
   {:pre [(vector? x)
          (= 2 (count vector))]}
   (= :fail (first x)))


Armor the short string pattern against punctuation

Because there are non-space characters that will commonly signal the end
of a "word" such as a short thing string.

--- src/grimoire/things.clj
+++ src/grimoire/things.clj
@@ -437,7 +437,7 @@
       t)))

 (def short-string-pattern
-  #"(\w{3,6})::([^\s/:]+)(/([^:\s]+))?")
+  #"(\w{3,6})::([^\s/,;:\"'\[\]\(\)\s]+)(/([^,;:\"'\[\]\(\)\s]+))?")

 (defn thing->short-string
   "Function from a Thing to a String representing a mostly unique naming string.


Fix namespace error

Fix namespace error

--- frontend/chemtrack/frontend/render.cljs
+++ frontend/chemtrack/frontend/render.cljs
@@ -1,5 +1,5 @@
 (ns chemtrack.frontend.render
-  (:require [chemtrack.template :as t]
+  (:require [chemtrack.frontend.template :as t]
             [cljs.core.async :as async]
             [clojure.string :as str]))


Relaxed the episode name check regular expression

--- src/ktra_indexer/db.clj
+++ src/ktra_indexer/db.clj
@@ -134,9 +134,9 @@
   (transaction
    (try
      (let [ep-name-parts (re-matches
-                          #"KTRA Episode (\d+)[\w\d\s:;-]* feat\. (.+)"
+                          #"KTRA Episode (\d+)[\w\d\s:;-]* (?:feat\.)?.+"
                           ep-name)]
-       (if-not (= (count ep-name-parts) 3)
+       (if-not (= (count ep-name-parts) 2)
          {:status "error"
           :cause "invalid-name"}
          (let [insert-res (kc/insert episodes


Fix indentation.

Fix indentation.

--- project/scrape-summitpost-data/test/scrape_summitpost_data/extract_test.clj
+++ project/scrape-summitpost-data/test/scrape_summitpost_data/extract_test.clj
@@ -1,6 +1,6 @@
 (ns scrape-summitpost-data.extract-test
   (:require [clojure.test :refer [deftest is]]
-           [scrape-summitpost-data.extract :as test-ns]))
+            [scrape-summitpost-data.extract :as test-ns]))

 (deftest ensure-sequence-test
   (is (= [1 2 3] (#'test-ns/ensure-sequence [1 2 3]))


Better command filtering. Track last tweet id.

--- src/myshelf/twitter.clj
+++ src/myshelf/twitter.clj
@@ -38,8 +38,15 @@
   [channel tweet]
   (let [cmd (make-command tweet)]
     (lb/publish channel default-exchange worker-queue
-                (json/generate-string cmd))
-    (:id tweet)))
+                (json/generate-string cmd))))
+
+(defn valid-command?
+  [tweet]
+  (->> tweet
+       :text
+       (re-find #"^myshelf-bot: (add|find|rank) ((\w|-+) ?)+$")
+       first
+       boolean))

 (defn check-tweets
   [channel creds screen-name current-id]
@@ -48,13 +55,15 @@
                 :params (merge {:screen-name screen-name
                                 :count 10}
                                (when current-id
-                                 {:since_id current-id})))]
+                                 {:since_id current-id})))
+        last-seen-id (:id (first (:body tweets)))]
     (->> tweets
          :body
          (sort-by :id)
-         (filter #(.contains (:text %) "myshelf-bot"))
+         (filter valid-command?)
          (map (partial send-command channel))
-         last)))
+         doall)
+    last-seen-id))

 (defn generate-status
   [{:keys [msg url sent-cmd sent-args results]}]


White space formatting of the TTP schema

--- src/cia/schemas/ttp.clj
+++ src/cia/schemas/ttp.clj
@@ -8,49 +8,77 @@

 (s/defschema AttackPattern
   "See http://stixproject.github.io/data-model/1.2/ttp/AttackPatternType/"
-  {:description (describe s/Str "text description of an individual Attack Pattern")
+  {:description
+   (describe s/Str "text description of an individual Attack Pattern")
+
    (s/optional-key :capec_id)
    (describe s/Str "a reference to a particular entry within the Common Attack Pattern Enumeration and Classification")})

 (s/defschema MalwareInstance
   "See http://stixproject.github.io/data-model/1.2/ttp/MalwareInstanceType/"
-  {:description (describe s/Str "text description of an individual Malware Instance")
-   :type (describe [v/MalwareType] "a characterization of what type of malware this")
+  {:description
+   (describe s/Str "text description of an individual Malware Instance")
+
+   :type
+   (describe [v/MalwareType] "a characterization of what type of malware this")
+
    ;; Not provided: name ; empty vocab
    })

 (s/defschema Behavior
   "See http://stixproject.github.io/data-model/1.2/ttp/BehaviorType/"
-  {(s/optional-key :attack_patterns) (describe [AttackPattern] "one or more Attack Patterns for this TTP")
-   (s/optional-key :malware_type) (describe [MalwareInstance] "one or more instances of Malware for this TTP")
+  {(s/optional-key :attack_patterns)
+   (describe [AttackPattern] "one or more Attack Patterns for this TTP")
+
+   (s/optional-key :malware_type)
+   (describe [MalwareInstance] "one or more instances of Malware for this TTP")
+
    ;; Not provided: exploits ; It is abstract
    })

 (s/defschema Infrastructure
   "See http://stixproject.github.io/data-model/1.2/ttp/InfrastructureType/"
-  {:description (describe s/Str "text description of specific classes or instances of infrastructure utilized for cyber attack")
-   :type (describe v/AttackerInfrastructure "represents the type of infrastructure being described")
+  {:description
+   (describe s/Str "text description of specific classes or instances of infrastructure utilized for cyber attack")
+
+   :type
+   (describe v/AttackerInfrastructure "represents the type of infrastructure being described")
+
    ;; Not provided: observable_characterization ; characterization of CybOX observables
    })

 (s/defschema Resource
   "See http://stixproject.github.io/data-model/1.2/ttp/ResourceType/"
-  {(s/optional-key :tools) (describe [c/Tool] "one or more Tools leveraged by this TTP")
-   (s/optional-key :infrastructure) (describe Infrastructure "infrastructure observed to have been utilized for cyber attack")
-   (s/optional-key :providers) [c/Identity]})
+  {(s/optional-key :tools)
+   (describe [c/Tool] "one or more Tools leveraged by this TTP")
+
+   (s/optional-key :infrastructure)
+   (describe Infrastructure "infrastructure observed to have been utilized for cyber attack")
+
+   (s/optional-key :providers)
+   [c/Identity]})

 (s/defschema VictimTargeting
   "See http://stixproject.github.io/data-model/1.2/ttp/VictimTargetingType/"
-  {(s/optional-key :identity) (describe c/Identity "infrastructure observed to have been utilized for cyber attack")
-   (s/optional-key :targeted_systems) (describe [v/SystemType] "type of system that is targeted")
-   (s/optional-key :targeted_information) (describe [v/InformationType] "a type of information that is targeted")
-   (s/optional-key :targeted_observables) (describe [c/Observable] "targeted observables")}) ;; Was targeted_technical_details
+  {(s/optional-key :identity)
+   (describe c/Identity "infrastructure observed to have been utilized for cyber attack")
+
+   (s/optional-key :targeted_systems)
+   (describe [v/SystemType] "type of system that is targeted")
+
+   (s/optional-key :targeted_information)
+   (describe [v/InformationType] "a type of information that is targeted")
+
+   (s/optional-key :targeted_observables)
+   (describe [c/Observable] "targeted observables")}) ;; Was targeted_technical_details

 (s/defschema TTP
   "See http://stixproject.github.io/data-model/1.2/ttp/TTPType/"
   (merge
    c/GenericStixIdentifiers
-   {:valid_time (describe c/ValidTime "a timestamp for the definition of a specific version of a TTP item")
+   {:valid_time
+    (describe c/ValidTime "a timestamp for the definition of a specific version of a TTP item")
+
     (s/optional-key :version)
     (describe s/Str "the relevant schema version for this content")

@@ -76,8 +104,12 @@
     (describe s/Str "source of this cyber threat TTP")

     ;; Extension fields:
-    :type  (describe s/Str "type of this TTP")
-    :indicators (describe [rel/IndicatorReference] "related indicators")
+    :type
+    (describe s/Str "type of this TTP")
+
+    :indicators
+    (describe [rel/IndicatorReference] "related indicators")
+
     ;; Not provided: kill_chain_phases
     ;; Not provided: kill_chains
     ;; Not provided: handling


Make clj-record.util/id-query-for a multimethod.

--- src/clj_record/util.clj
+++ src/clj_record/util.clj
@@ -16,13 +16,13 @@
       (some #(.endsWith lc %) ["s" "z" "ch" "sh" "x"]) (str lc "es")
       :else (str lc "s"))))

-(defn id-query-for [{:keys [subprotocol] :as db-spec} table-name]
-  (cond
-    (= subprotocol "derby")
-      "VALUES IDENTITY_VAL_LOCAL()"
-    (= subprotocol "postgresql")
-      (str "SELECT currval(pg_get_serial_sequence('" table-name "','id'))")
-    (= subprotocol "mysql")
-      "SELECT LAST_INSERT_ID()"
-    :else
-      (throw (Exception. (str "Unrecognized db-spec: " db-spec)))))
+(defmulti  id-query-for :subprotocol)
+(defmethod id-query-for "derby" [_ _]
+  "VALUES IDENTITY_VAL_LOCAL()")
+(defmethod id-query-for "postgresql" [_ table-name]
+  (str "SELECT currval(pg_get_serial_sequence('" table-name "','id'))"))
+(defmethod id-query-for "mysql" [_ _]
+  "SELECT LAST_INSERT_ID()")
+(defmethod id-query-for :default [db-spec _]
+  (throw (Exception. (str "Unrecognized db-spec subprotocol: " db-spec))))
+


Fix key event processing.

Fix key event processing.

--- src/cljc/quil/core.cljc
+++ src/cljc/quil/core.cljc
@@ -2199,7 +2199,7 @@
   ClojureScript."
      []
      (let [modifiers
-           (if-let [^java.awt.event.InputEvent
+           (if-let [^processing.event.Event
                     event (-> (ap/current-applet) meta :key-event deref)]
              [(if (.isAltDown event) :alt nil)
               (if (.isShiftDown event) :shift nil)


Add regexp method stubs.

Add regexp method stubs.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -1476,6 +1476,24 @@
     (if (and xs (pos? n))
       (recur (dec n) (next xs))
       xs)))
+
+(defn re-find
+  "Returns the first regex match, if any, of string to pattern, using
+  RegExp.exec(string)."
+  [re s]
+  (let [matches (.exec re s)]
+    (when-not (nil? matches) (nth matches 0))))
+
+(defn re-seq
+  "Returns a sequence of successive matches of pattern in string,
+  using String.match(regex)."
+  [re s]
+  (seq (.match s re)))
+
+(defn re-pattern
+  "Returns an instance of RegExp which has compiled the provided string."
+  [s]
+  (.compile (goog.global.RegExp.) s "g"))

 ;;; Vector


count check in equiv-sequential if both arguments are ICounted

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -2057,12 +2057,15 @@
   returns false."
   [x y]
   (boolean
-   (when (sequential? y)
-     (loop [xs (seq x) ys (seq y)]
-       (cond (nil? xs) (nil? ys)
-             (nil? ys) false
-             (= (first xs) (first ys)) (recur (next xs) (next ys))
-             :else false)))))
+    (when (sequential? y)
+      (if (and (counted? x) (counted? y)
+               (not (== (count x) (count y))))
+        false
+        (loop [xs (seq x) ys (seq y)]
+          (cond (nil? xs) (nil? ys)
+            (nil? ys) false
+            (= (first xs) (first ys)) (recur (next xs) (next ys))
+            :else false))))))

 (defn- hash-coll [coll]
   (if (seq coll)


Removed unused function to print-and-flush message

--- src/clouseau/server.clj
+++ src/clouseau/server.clj
@@ -46,13 +46,6 @@
 (require '[clouseau.html-renderer :as html-renderer])
 (require '[clouseau.text-renderer :as text-renderer])
 (require '[clouseau.db-interface  :as db-interface])
-
-(defn println-and-flush
-    "Original (println) has problem with syncing when it's called from more threads.
-     This function is a bit better because it flushes all output immediatelly."
-    [& more]
-    (.write *out* (str (clojure.string/join " " more) "\n"))
-    (flush))

 (defn read-description
     "Read description from the database for specified product and package."


Better tests for destruction order

Better tests for destruction order

--- test/yadic/core_test.clj
+++ test/yadic/core_test.clj
@@ -137,41 +137,45 @@
 ; Destructors
 ; ==================================

+(defn close-recording
+  [close-was-called-with activator]
+  (let [activator (as-activator activator)]
+
+    (reify
+      Activator
+      (activate [this container]
+        (activate activator container))
+
+      (close [this instance]
+        (swap! close-was-called-with conj instance)
+        (close activator instance)))))
+
 (fact "Activators can specify destructors, which are called when the container is closed"
-  (let [close-was-called-with (atom nil)
+  (let [close-was-called-with (atom [])
         activators            (->activators :a
-                                            (reify
-                                              Activator
-                                              (activate [this container] "the instance")
-                                              (close [this instance]
-                                                (reset! close-was-called-with instance))))
+                                            (close-recording close-was-called-with
+                                              (concrete "the instance")))
         container             (->container activators)]
     (:a container) => "the instance"
     (.close container)
-    @close-was-called-with => "the instance"))
+    @close-was-called-with => ["the instance"]))

 (fact "Destructors aren't called if the instance isn't realised"
-  (let [close-was-called (atom false)
-        activators       (->activators :a
-                                       (reify
-                                         Activator
-                                         (activate [this container] "never activated")
-                                         (close [this instance]
-                                           (reset! close-was-called true))))
+  (let [close-order (atom [])
+        activators       (->activators
+                           :a (close-recording close-order
+                                         (concrete "never-activated")))
         container        (->container activators)]
     (.close container)
-    @close-was-called => false))
+    @close-order => []))

 (fact "Destructors are called in reverse order of activation"
   (let [close-order (atom [])
         ks          (map (comp keyword str) (range 100))
         activators  (->> ks
                          (map (fn [k]
-                                (reify
-                                  Activator
-                                  (activate [this container] k)
-                                  (close [this instance]
-                                    (swap! close-order conj k)))))
+                                (close-recording close-order
+                                  (concrete k))))
                          (zipmap ks)
                          (->activators))
         container   (->container activators)]
@@ -182,6 +186,28 @@
     (.close container)

     @close-order => (reverse ks)))
+
+(fact "Destructors are called in reverse order of activation, even through dependency chains"
+  (let [close-order (atom [])
+        activators  (->activators :a (close-recording close-order
+                                       (act [] "a"))
+                                  :b (close-recording close-order
+                                       (act [a] (str a "b")))
+                                  :c (close-recording close-order
+                                       (act [b] (str b "c")))
+                                  :d (close-recording close-order
+                                       (act [c] (str c "d")))
+                                  :e (close-recording close-order
+                                       (act [d] (str d "e"))))
+        container   (->container activators)]
+
+    (get container :b) => "ab"
+
+    (get container :e) => "abcde"
+
+    (.close container)
+
+    @close-order => ["abcde" "abcd" "abc" "ab" "a"]))

 (deftype ACloseableType [closed-atom]
   AutoCloseable


Improve parameter descriptions on info-button

--- src/re_com/buttons.cljs
+++ src/re_com/buttons.cljs
@@ -185,12 +185,12 @@
 ;;--------------------------------------------------------------------------------------------------

 (def info-button-args-desc
-  [{:name :info             :required false                          :type "hiccup"     :description "show a popover-tooltip using this markup."}
-   {:name :position         :required false :default ":right-below"  :type "keyword"    :description "position of the popover-tooltip. e.g. :right-below."}
-   {:name :width            :required false :default "250px"         :type "string"     :description "width in px"}
-   {:name :class            :required false                          :type "string"     :description "additional CSS classes required."}
-   {:name :style            :required false                          :type "map"        :description "CSS styles to add or override."}
-   {:name :attr             :required false                          :type "map"        :description "html attributes to add or override (:class/:style not allowed)."}])
+  [{:name :info             :required false                          :type "string | hiccup" :description "What's shown in the popover."}
+   {:name :position         :required false :default ":right-below"  :type "keyword"         :description "position of the popover-tooltip. e.g. :right-below."}
+   {:name :width            :required false :default "250px"         :type "string"          :description "width in px"}
+   {:name :class            :required false                          :type "string"          :description "CSS classes"}
+   {:name :style            :required false                          :type "map"             :description "CSS styles to add or override."}
+   {:name :attr             :required false                          :type "map"             :description "html attributes to add or override (:class/:style not allowed)."}])

 (def info-button-args
   (set (map :name info-button-args-desc)))


Fix cut-n-paste error in tagged-any docstring (#1015)

--- src/riemann/streams.clj
+++ src/riemann/streams.clj
@@ -1318,7 +1318,7 @@

   ```clojure
   (tagged-any \"foo\" prn)
-  (tagged-all [\"foo\" \"bar\"] prn)
+  (tagged-any [\"foo\" \"bar\"] prn)
   ```"
   [tags & children]
   (let [tag-coll (flatten [tags])]


fix cogroup

fix cogroup

--- src/datasplash/core.clj
+++ src/datasplash/core.clj
@@ -897,11 +897,11 @@
                               (map #(.getTupleTag %))
                               (sort-by #(.getId %)))
             rel (.apply pcolltuple (with-opts base-schema opts (CoGroupByKey/create)))
-            final-rel (dmap (fn [elt]
+            final-rel (dmap (fn [^KV elt]
                               (let [k (.getKey elt)
                                     raw-values (.getValue elt)
                                     values (for [tag ordered-tags]
-                                             (into [] (first (.getAll raw-values tag))))]
+                                             (seq (.getAll raw-values tag)))]
                                 (into [] (conj values k))))
                             (assoc opts :without-coercion-to-clj true)
                             rel)]


Make the test pass

Make the test pass

--- src/desdemona/query.clj
+++ src/desdemona/query.clj
@@ -45,7 +45,11 @@

     [(('and & terms) :seq)]
     (let [logic-terms (map dsl->logic terms)]
-      `(l/conde [~@logic-terms]))))
+      `(l/conde [~@logic-terms]))
+
+    [(('or & terms) :seq)]
+    (let [clauses (map (comp vector dsl->logic) terms)]
+      `(l/conde ~@clauses))))

 (defn run-dsl-query
   "Run a DSL query over some events and finds n answers (default 1)."


removed fuse-row- and fuse because deprecated + removed mapr because map-rows already do the job

--- src/grafter/tabular.clj
+++ src/grafter/tabular.clj
@@ -266,24 +266,7 @@
     (reduce remove-index col pos)))

-  (defn- fuse-row [columns f row]
-    (let [to-drop (drop 1 (sort columns))
-          merged (assoc row (apply min columns)
-                        (apply f (select-columns-from-row columns row)))]
-      (apply remove-indices merged to-drop)))
-
-  (defn fuse [csv f & cols]
-    "Merge columns with the specified function f receives the number of
-cols supplied number of arguments e.g. If you fuse 3 columns f
-must accept 3 arguments"
-    (map (partial fuse-row cols f) csv))
-
 (comment
-
-  (defn mapr [csv f]
-    "Logically identical to map but with reversed arguments, so it works
-better with -> .  mapr maps f over each row."
-    (map f csv))

   (defn mapc [csv fs]
     "Takes an array of functions and maps each to the equivalent column


Add Note, Example to Thing

Add Note, Example to Thing

Add structures for representing the handle of Notes on an arbitrary
thing, Examples on an arbitrary thing.

--- src/grimoire/things.clj
+++ src/grimoire/things.clj
@@ -3,13 +3,17 @@
   uniquely naming and referencing entities in a Grimoire documentation
   store.

-  Thing     ::= Sum[Group, Artifact, Version, Platform, Namespace, Def];
+  Thing     ::= Sum[Group, Artifact, Version, Platform,
+                    Namespace, Def, Note, Example];
   Group     ::= Record[                   Name: String];
   Artifact  ::= Record[Parent: Group,     Name: String];
   Version   ::= Record[Parent: Artifact,  Name: String];
   Platform  ::= Record[Parent: Version,   Name: String];
   Namespace ::= Record[Parent: Platform,  Name: String];
-  Def       ::= Record[Parent: Namespace, Name: String];"
+  Def       ::= Record[Parent: Namespace, Name: String];
+
+  Note      ::= Record[Parent: Thing,     Handle: String];
+  Example   ::= Record[Parent: Thing,     Handle: String];"
   (:refer-clojure :exclude [def namespace])
   (:require [clojure.string :as string]
             [grimoire.util :as u]
@@ -62,30 +66,58 @@
   {:pre [(namespace? parent)
          (string? name)]})

+(declare thing?)
+
+(v/deftag note
+  "Represents a single block of notes on an arbitrary Thing as
+  identified by a Handle. The Handle is intended to be some structure
+  such as a file path, record ID, UUID or something else uniquely
+  naming a specific note."
+  [parent, handle]
+  {:pre [(thing? parent)
+         (string? handle)]})
+
+(def ->Note "Alias for ->note." ->note)
+
+(v/deftag example
+  "Represents a single example on an arbitrary Thing as identified by
+  a Handle. The Handle is intended to be some structure such as a file
+  path, record ID, UUID or other unique identifier for that singular
+  specific example."
+  [parent, handle]
+  {:pre [(thing? parent)
+         (string? handle)]})
+
+(def ->Example "Alias for ->example." ->example)
+
 ;; Helpers for walking thing paths

+
+(defn leaf?
+  "Predicate testing whether the input Thing is either an example or a
+  note."
+  [t]
+  (or (note? t)
+      (example? t)))

 (defn namespaced?
   "Predicate testing whether the input either is a namespace or has a namespace
   as a parent."
   [t]
   (or (namespace? t)
-      (def? t)))
+      (def? t)
+      (and (leaf? t)
+           (namespaced? (:parent t)))))

 (defn platformed?
   "Predicate testing whether the input either is a platform or has a platform as
   a parent."
   [t]
   (or (namespaced? t)
-      (platform? t)))
-
-(defn artifacted?
-  "Predicate testing whether the input either is an artifact or has an artifact
-  as a parent."
-  [t]
-  (or (platformed? t)
-      (artifact? t)))
+      (platform? t)
+      (and (leaf? t)
+           (platformed? (:parent t)))))

 (defn versioned?
   "Predicate testing whether the input exists within the subset of the \"thing\"
@@ -94,21 +126,27 @@
   traversal."
   [t]
   (or (platformed? t)
-      (version? t)))
+      (version? t)
+      (and (leaf? t)
+           (versioned? (:parent t)))))

 (defn artifacted?
   "Predicate testing whether the input either is an artifact or has an artifact
   as a parent."
   [t]
   (or (versioned? t)
-      (artifact? t)))
+      (artifact? t)
+      (and (leaf? t)
+           (artifacted? (:parent t)))))

 (defn grouped?
   "Predicate testing whether the input either is a group or has a group as a
   parent."
   [t]
   (or (artifacted? t)
-      (group? t)))
+      (group? t)
+      (and (leaf? t)
+           (grouped? (:parent t)))))

 (defn thing?
   "Predicate testing whether the input exists within the \"thing\" variant of
@@ -127,8 +165,9 @@
   "Function from an object to Maybe[String]. If the input is a thing, returns
   the name of the Thing. Otherwise returns nil."
   [t]
-  (when (thing? t)
-    (:name t)))
+  {:pre [(thing? t)
+         (not (leaf? t))]}
+  (:name t))

 ;; Helpers for stringifying and reading paths


check for local item before trying to read it as clojure string

--- src/lib/cljs/local.cljs
+++ src/lib/cljs/local.cljs
@@ -4,12 +4,13 @@
 (defn local-storage? []
   (not (undefined? (.-localStorage js/window))))

-(defn get-item [key]
+(defn get-item [k]
   (if (local-storage?)
-    (. js/localStorage (getItem key))))
+    (. js/localStorage (getItem k))))

-(defn get-clojure [id]
-  (reader/read-string (get-item id)))
+(defn get-clojure [k]
+  (if-let [item (get-item k)]
+    (reader/read-string item)))

 (defn set-item [k v]
   (if (local-storage?)


Show cursor when selecting text

Show cursor when selecting text

--- src/lt/objs/editor.cljs
+++ src/lt/objs/editor.cljs
@@ -46,7 +46,8 @@
                      :dragDrop false
                      :onDragEvent (fn [] true)
                      :undoDepth 10000
-                     :matchBrackets true})]
+                     :matchBrackets true
+                     :showCursorWhenSelecting true})]
     (when-let [c (:content context)]
       (set-val e c)
       (clear-history e))


remove unneeded js scripts

remove unneeded js scripts

--- src/mail_query/view.clj
+++ src/mail_query/view.clj
@@ -54,6 +54,5 @@
               [:div.pure-u-1 "There are no items."])]
            [:div.pure-u-1
             [:h2 "New Query"]
-            (query-form)]]
-          [:script {:src "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"}]]))
+            (query-form)]]]))


DRY. Use exist funcs.

DRY. Use exist funcs.

--- src/ombs/db/payment.clj
+++ src/ombs/db/payment.clj
@@ -93,25 +93,13 @@
                                        (sql/fields :summ)
                                        (sql/aggregate (sum :money) :summ))))))

-(defn- fixer
-  ([r] (-> r
-           first
-           f/nil-fix))
-  ([t r] (-> r
-             first
-             t
-             f/nil-fix)))
+(defn get-feesed-parts [eid]
+  "Select sum of parts, that contained in fees for given event id."
+  (:sum (first (sql/select fees
+                           (sql/where {:events_id eid})
+                           (sql/aggregate (sum :parts) :sum)))))

 (defn free-parts [eid]
   "Return num of parts, that can be payed."
-  (let [
-        actual (fixer :rest
-                      (sql/select goods
-                                  (sql/fields :rest)
-                                  (sql/where {:events_id eid}) ))
-        feesed (fixer :sum
-                      (sql/select fees
-                                  (sql/where {:events_id eid})
-                                  (sql/aggregate (sum :parts) :sum)))
-        ]
-    (- actual feesed)))
+  (- (f/nil-fix (get-rest-parts eid))
+     (f/nil-fix (get-feesed-parts eid))))


CMR-5260: Added tests for UMM-G granule validation endpoint.

--- system-int-test/test/cmr/system_int_test/ingest/granule_validation_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/granule_validation_test.clj
@@ -3,6 +3,8 @@
   (:require
     [clj-time.core :as t]
     [clj-time.format :as tf ]
+    [clojure.java.io :as io]
+    [clojure.java.shell :as shell]
     [clojure.test :refer :all]
     [cmr.common.time-keeper :as tk]
     [cmr.common.util :refer [are2]]
@@ -431,3 +433,74 @@
   ;; Turn it back on after the test
   (dev-sys-util/eval-in-dev-sys
    `(cmr.metadata-db.services.concept-constraints/set-enforce-granule-ur-constraint! true)))
+
+(def ^:private coll-file
+  "temp file for collection metadata"
+  "collection.xml")
+
+(def ^:private granule-file
+  "temp file for granule metadata"
+  "granule.json")
+
+(defn- validate-granule-multipart
+  "Returns the validation result of the granule with the given collection and granule
+  through multiparts request."
+  [granule-concept coll-concept]
+  ;; clj-http does not work with content-type that contains semicolons
+  ;; (e.g. application/vnd.nasa.cmr.umm+json; version=1.4)
+  ;; So we execute curl command directly from shell for UMM-G granule validation requests
+  (let [coll-fiile ""])
+  (try
+    (spit coll-file (:metadata coll-concept))
+    (spit granule-file (:metadata granule-concept))
+    (let [{:keys [provider-id native-id]} granule-concept
+          validate-url (url/validate-url provider-id :granule native-id)
+          coll-form (format "collection=<%s;type=%s" coll-file (:format coll-concept))
+          granule-form (format "granule=<%s;type=%s" granule-file (:format granule-concept))]
+      (let [{:keys [out]} (shell/sh "curl" "-i" "-F" granule-form "-F" coll-form validate-url)]
+        out))
+    (finally
+      (io/delete-file coll-file)
+      (io/delete-file granule-file))))
+
+(defn- validate-granule-multipart-ok?
+  "Validate the granule multipart request returns 200 OK"
+  [granule-concept coll-concept]
+  (is (re-find
+       #"200 OK"
+       (validate-granule-multipart granule-concept coll-concept))))
+
+(defn- validate-granule-multipart-failed?
+  "Validate the granule multipart request returns the expected status code and error message."
+  [granule-concept coll-concept status-code error-msg]
+  (is (re-find
+       (re-pattern (str "(?s)" status-code ".*" error-msg))
+       (validate-granule-multipart granule-concept coll-concept))))
+
+(deftest validation-umm-g-granule-test
+  (testing "with collection as additional parameter"
+    (let [collection-attrs {:EntryTitle "correct"
+                            :ShortName "S1"
+                            :Version "V1"}
+          collection-ref-attrs {:entry-title "correct"
+                                :short-name "S1"
+                                :version-id "V1"}
+          collection (data-umm-c/collection collection-attrs)
+          coll-concept (d/umm-c-collection->concept collection :iso-smap)
+          coll-concept-id (:concept-id collection)]
+      (testing "valid UMM-G granule"
+        (let [granule (assoc (dg/granule-with-umm-spec-collection collection nil)
+                             :collection-ref
+                             (umm-g/map->CollectionRef collection-ref-attrs))
+              granule-concept (d/item->concept granule :umm-json)]
+          (validate-granule-multipart-ok? granule-concept coll-concept)))
+
+      (testing "invalid UMM-G granule"
+        (let [granule (assoc (dg/granule-with-umm-spec-collection collection nil)
+                             :collection-ref
+                             (umm-g/map->CollectionRef (merge collection-ref-attrs {:entry-title "wrong"})))
+              granule-concept (d/item->concept granule :umm-json)
+              expected-err-msg (str "Collection Reference Entry Title \\[wrong\\] does not match "
+                                    "the Entry Title of the parent collection \\[correct\\]")]
+          (validate-granule-multipart-failed?
+           granule-concept coll-concept 422 expected-err-msg))))))


Add example to type hints stuff…

Add example to type hints stuff…

…What happens when the type hint matches the actual arg.

--- test/com/nomistech/clojure_the_language/old_to_organise/type_hints_test.clj
+++ test/com/nomistech/clojure_the_language/old_to_organise/type_hints_test.clj
@@ -8,6 +8,11 @@

 (defn f [^String s]
   (identity s))
+
+(fact
+  (f "foo")
+  => "foo" ; as expected
+  )

 (fact
   (f 42)


Added a feature to most buttons to prevent the tooltip from still showing after a button is included in a drag/drop

--- src/re_com/buttons.cljs
+++ src/re_com/buttons.cljs
@@ -30,6 +30,7 @@
           :or   {class "btn-default"}
           :as   args}]
       {:pre [(validate-args-macro button-args-desc args "button")]}
+      (when-not tooltip (reset! showing? false)) ;; To prevent tooltip from still showing after button drag/drop
       (let [disabled? (deref-or-value disabled?)
             the-button [:button
                         (merge
@@ -83,6 +84,7 @@
           :or   {md-icon-name "zmdi-plus"}
           :as   args}]
       {:pre [(validate-args-macro md-circle-icon-button-args-desc args "md-circle-icon-button")]}
+      (when-not tooltip (reset! showing? false)) ;; To prevent tooltip from still showing after button drag/drop
       (let [the-button [:div
                         (merge
                           {:class    (str
@@ -139,6 +141,7 @@
           :or   {md-icon-name "zmdi-plus"}
           :as   args}]
       {:pre [(validate-args-macro md-icon-button-args-desc args "md-icon-button")]}
+      (when-not tooltip (reset! showing? false)) ;; To prevent tooltip from still showing after button drag/drop
       (let [the-button [:div
                         (merge
                           {:class    (str
@@ -235,6 +238,7 @@
           :or   {md-icon-name "zmdi-plus"}
           :as   args}]
       {:pre [(validate-args-macro row-button-args-desc args "row-button")]}
+      (when-not tooltip (reset! showing? false)) ;; To prevent tooltip from still showing after button drag/drop
       (let [the-button [:div
                         (merge
                           {:class    (str
@@ -283,6 +287,7 @@
     (fn
       [& {:keys [label on-click tooltip tooltip-position disabled? class style attr] :as args}]
       {:pre [(validate-args-macro hyperlink-args-desc args "hyperlink")]}
+      (when-not tooltip (reset! showing? false)) ;; To prevent tooltip from still showing after button drag/drop
       (let [label      (deref-or-value label)
             disabled?  (deref-or-value disabled?)
             the-button [box
@@ -335,6 +340,7 @@
     (fn
       [& {:keys [label href target tooltip tooltip-position class style attr] :as args}]
       {:pre [(validate-args-macro hyperlink-href-args-desc args "hyperlink-href")]}
+      (when-not tooltip (reset! showing? false)) ;; To prevent tooltip from still showing after button drag/drop
       (let [label      (deref-or-value label)
             href       (deref-or-value href)
             target     (deref-or-value target)


Fix log coalescing

Fix log coalescing

--- src/robinson/update.clj
+++ src/robinson/update.clj
@@ -1099,20 +1099,24 @@
 (defn init-log-scrolling
   [state]
   (-> state
-    (update-in [:world :logs]
+    (update-in [:world :log]
       (fn [logs]
         (mapcat
           (fn [logs-with-same-time]
             (vec
               (reduce (fn [logs-with-same-time log]
-                        (if (< (+ (count (get (last logs-with-same-time) :message))
-                                  (count (get log :message)))
-                                70)
-                          (vec (conj (butlast logs-with-same-time)
-                                      {:time (get log :time)
-                                       :message (clojure.string/join " " [(get (last logs-with-same-time) :message)
-                                                                          (get log :message)])}))
-                          (conj logs-with-same-time log)))
+                        (let [last-log (last logs-with-same-time)]
+                          (if (and (< (+ (count (get last-log :text))
+                                      (count (get log :text)))
+                                    70)
+                                (= (get last-log :color)
+                                   (get log :color)))
+                            (vec (conj (butlast logs-with-same-time)
+                                        {:time (get log :time)
+                                         :text (clojure.string/join " " [(get last-log :text)
+                                                                         (get log :text)])
+                                         :color (get log :color)}))
+                            (conj logs-with-same-time log))))
                       []
                       logs-with-same-time)))
           (vals (group-by :time logs)))))


Finished clojure day 2

Finished clojure day 2

--- clojure-days/src/clojure_days/day_2.clj
+++ clojure-days/src/clojure_days/day_2.clj
@@ -66,6 +66,14 @@

 ;;; DO

+;; Implement an unless with an else condition using macros.
+(defmacro unless [condition body else-body]
+  (list 'if (list 'not condition) body else-body))
+
+(unless true (println "body") (println "else-body"))
+(unless false (println "body") (println "else-body"))
+
+
 ;; Write a type using defrecord that implements a protocol.
 (defprotocol Employee
   (nick [x] "The nickname of the Employee.")


Arghh, parens

Arghh, parens

--- satori-rules/rules/mysql/query.clj
+++ satori-rules/rules/mysql/query.clj
@@ -25,7 +25,7 @@
          :user "user_for_monitor"
          :password "Secret!IMeanIt!"
          :database "awesome_app"
-         :sql "SELECT count(*) FROM user"})))
+         :sql "SELECT count(*) FROM user"}))

     (where (service "mysql.query.bad-user-count")
       (set-state (> 50)
@@ -33,7 +33,7 @@
           (should-alarm-every 300
             (! {:note "坏用户太多了！"
                 :level 3
-                :groups [:operation]}))))
+                :groups [:operation]})))))

     (where (service #"^mysql\.query\..*-user-count$")
       (slot-window :service {:total "mysql.query.total-user-count",


make cond statement more clear

make cond statement more clear

--- bake/bake/test.clj
+++ bake/bake/test.clj
@@ -18,9 +18,10 @@
     (symbol str)))

 (defn group-opts [coll]
-  (group-by #(cond (and (namespace %) (name %)) :fn
-                   (keyword? %) :tag
-                   :else :ns)
+  (group-by #(cond (and (namespace %)
+                        (name %))     :fn
+                   (keyword? %)       :tag
+                   :else              :ns)
             coll))

 (defn get-grouped-tests [namespaces opts]


fix test reporting for fns

fix test reporting for fns

--- bake/bake/test.clj
+++ bake/bake/test.clj
@@ -57,6 +57,10 @@
   (clojure.test/with-test-out
     (print-results m)))

+(defmethod clojure.test/report :fn-summary [m]
+  (clojure.test/with-test-out
+    (print-results m)))
+
 (defmethod clojure.test/report :begin-auto [m])

 (defmethod clojure.test/report :summary-auto [m]
@@ -88,9 +92,12 @@
 (defn run-tests-for-fns [grouped-tests]
   (when-let [input-fs (:fn grouped-tests)]
     (println "testing functions:" (apply str (interpose ", " input-fs)))
-    (binding [clojure.test/*report-counters* (ref clojure.test/*initial-report-counters*)]
-      (doseq [f input-fs] (clojure.test/test-var (ns-resolve (symbol (namespace f)) (symbol (name f)))))
-      (list (assoc @clojure.test/*report-counters* :type :fns)))))
+    (binding [clojure.test/*report-counters* (ref clojure.test/*initial-report-counters*)
+              start-time (System/nanoTime)]
+      (doseq [f input-fs]
+        (clojure.test/test-var (ns-resolve (symbol (namespace f))
+                                           (symbol (name f)))))
+      (clojure.test/report (assoc @clojure.test/*report-counters* :type :fn-summary :start-time start-time)))))

 (defn run-tests-for-nses [grouped-tests]
   (for [ns (:ns grouped-tests)]


Fix bugs that caused by spec 0.2.168 update

--- src/spectrace/core.cljc
+++ src/spectrace/core.cljc
@@ -65,7 +65,7 @@

 (defmethod step `s/tuple [{:keys [spec path val in ::pred] :as state}]
   (if (empty? path)
-    (do (assert (or (= pred 'vector?)
+    (do (assert (or (#{'vector? `vector?} pred) ;; need to accept vector? for backward compatibility
                     (s/valid? (s/cat := `#{=} :count `#{(count ~'%)}
                                      :n integer?)
                               pred)))
@@ -130,7 +130,7 @@
                       & {:keys [val-fn]}]
   (let [keys (possible-keys (rest spec))]
     (if (empty? path)
-      (if (= pred 'map?)
+      (if (#{'map? `map?} pred) ;; need to accept map? for backward compatibility
         (assoc state :spec pred)
         (let [fn? (s/cat :fn `#{fn} :args (s/tuple '#{%})
                          :body (s/and seq?


~(deftest roundtrip-np-grammar): {:phrasal true}

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -258,7 +258,8 @@
 ;; deftest's 'do-this-many' below.
 (deftest roundtrip-np-grammar
   (let [do-this-many 10
-        spec {:synsem {:cat :noun
+        spec {:phrasal true
+              :synsem {:cat :noun
                        :subcat []
                        :agr {:gender :top
                              :number :top}


extract out render-board from tile-grid

extract out render-board from tile-grid

--- src/tile_game/grid.cljs
+++ src/tile_game/grid.cljs
@@ -32,6 +32,12 @@
             :on-change (fn [e] (swap! app-state assoc :size (.-target.value e)))
             :style {:width "25%"}}]])

+(defn render-board [board dim commmand]
+  [:svg {:view-box (str "0 0 " dim " " dim) :width 800 :height 800}
+   (for [x (range dim) y (range dim)]
+     (let [tile (nth board (+ (* y dim) x))]
+       (render-tile [x y] tile command)))])
+
 (defn render-tile [[x y] tile command]
   (if-not (zero? tile)
     (let [fill-color (nth colors tile)]
@@ -59,10 +65,7 @@
         dim (b/dimension board)]
     [:center
      [:h1 "Tile Puzzle"]
-     [:svg {:view-box (str "0 0 " dim " " dim) :width 800 :height 800}
-      (for [x (range dim) y (range dim)]
-        (let [tile (nth board (+ (* y dim) x))]
-          (render-tile [x y] tile command)))]
+     (render-board board dim command)
      [:h4 (if (b/solved? board) "Solved!" "Slide tiles with arrow keys or clicking on tile")]
      [:details [:summary (str (count moves) " moves.")] (str moves)]
      (board-size-slider size command)


Only show analysis mode optionally

Only show analysis mode optionally

--- src/tile_game/grid.cljs
+++ src/tile_game/grid.cljs
@@ -12,7 +12,8 @@

 (defonce app-state
   (r/atom {:board (b/create-board 4)
-           :size 4}))
+           :size 4
+           :analysis-mode false}))

 (defn new-board! [& args]
   #(swap! app-state assoc :board (apply b/create-board args)))
@@ -39,7 +40,7 @@
         (str tile)]])))

 (defn tile-grid []
-  (let [{:keys [board size]} @app-state
+  (let [{:keys [board size analysis-mode]} @app-state
         dim (b/dimension board)]
     [:center
      [:h1 "Tile Puzzle"]
@@ -47,10 +48,17 @@
       (for [x (range dim) y (range dim)]
         (let [tile (nth board (+ (* y dim) x))]
           (render-tile [x y] tile)))]
-     [:div (if (b/solved? board)
-             "Solved!"
-             (str "Suggested Moves: " (b/solve-next board)))]
+     [:h4 (if (b/solved? board) "Solved!" "Slide tiles with arrow keys or clicking on tile")]
      (board-size-slider size)
+     [:div
+      [:label "Analysis Mode"]
+      [:input {:type "checkbox" :checked analysis-mode
+               :on-click #(swap! app-state update-in [:analysis-mode] not)}]
+      [:br]
+      (when analysis-mode
+        (if (b/solved? board)
+          "Solved!"
+          (str "Suggested Moves: " (b/solve-next board))))]
      [:p
       "© 2017 Charles L.G. Comstock "
       [:a {:href "https://github.com/dgtized/tile-game"} "(github)"]]]))


Add formatted output.

Add formatted output.

Add formatting of output. This change requires an additional npm module,
sprintf.

The code is "odd" requiring a call like `(.sprintf sprintf ...)`. I
think I can fix this by using `partial`, but I want to capture this
working code before investigating this change.

--- src/time_calc/core.cljs
+++ src/time_calc/core.cljs
@@ -9,6 +9,8 @@
 (defrecord TimeInterval [hours mins])

 (def fs (js/require "fs"))
+
+(def sprintf (js/require "sprintf-js"))

 (nodejs/enable-util-print!)

@@ -93,13 +95,11 @@
     (into {} (for [[d i] interval-map]
                [d (interval->decimal-interval i)]))))

-;; (defn summarize-tasks [tasks] {"mots" 3.75 "atrog" 4.25})
-
 (defn report-summary [summary]
   "Reports the summary of tasks."
   (doseq [[details duration]
           (sort-by first summary)]
-    (println details (float duration))))
+    (println (.sprintf sprintf "%-12s %5.2f" details (float duration)))))

 (defn -main [& args]
   (let [time-file-name (if args


removing kruft

removing kruft

--- src/timsg/scene_var.clj
+++ src/timsg/scene_var.clj
@@ -2,128 +2,8 @@
   (:refer-clojure :exclude [def])
   (:use [arcadia.core])
   (:require [clojure.spec :as s]
-            [clojure.core :as c]
-            [arcadia.internal.spec :as as])
+            [clojure.core :as c])
   (:import [UnityEngine GameObject Component]))
-
-;; ============================================================
-;; utils
-
-;; until it's a thing:
-(defn- hook-replace
-  "Remove all `hook` components attached to `obj` at `k` and replace with `f`"
-  [obj hook k f]
-  (hook- obj hook k)
-  (hook+ obj hook k f))
-
-;; ============================================================
-;; plumbing
-
-;; think you only need one piece of state and a callback on the object
-
-(defonce ^:private name-registry
-  (atom {::objs->names {}
-         ::names->objs {}}))
-
-(defn- remove-name-obj [reg name obj]
-  (-> reg
-      (update ::objs->names dissoc obj)
-      (update ::names->objs dissoc name)))
-
-(defn- put-name-obj [{:keys [::objs->names ::names->objs]
-                      :as reg},
-                     name, obj]
-  (let [old-obj (get names->objs name)
-        old-name (get objs->names obj)]
-    (-> reg
-        (remove-name-obj old-name old-obj)
-        (update ::objs->names assoc obj name)
-        (update ::names->objs assoc name obj))))
-
-(defn- handle-obj-destroy [^GameObject obj]
-  (swap! name-registry
-    (fn [reg]
-      (when-let [name (-> reg (get ::objs->names) (get obj))]
-        (remove-name-obj reg name obj)))))
-
-(defn- register-name [^GameObject obj, name]
-  (hook-replace obj :on-destroy ::scene-var #'handle-obj-destroy)
-  (swap! name-registry #(put-name-obj % name obj)))
-
-(defn find-entity [name]
-  (-> @name-registry
-      (get ::names->objs)
-      (get name)))
-
-(defn- run-init [init-fn name]
-  (when-let [ent (init-fn)]
-    (when-not (instance? GameObject ent)
-      (throw
-        (Exception.
-          (str "Zero-argument arity of def-entity, if present, must return a GameObject; instead getting a " (type ent)))))
-    ent))
-
-;; ==================================================
-;; never mind, just use a fucking var
-
-(defn init-entity [{:keys [kw init update] :as init-spec}]
-  (-> (or (find-entity kw)
-          (and init (run-init init kw)))
-      (as-> ent
-            (if update (update ent) ent)
-            (register-name ent kw))))
-
-;; ============================================================
-;; def-entity
-
-;; TODO: support for docs
-
-(s/def ::tail-impl
-  (s/cat
-    :args (s/and vector? #(#{0 1} (count %)))
-    :tail (s/* any?)))
-
-(s/def ::def-entity-args
-  (s/cat
-    :name symbol?
-    :tails (s/alt
-             :single-arity ::tail-impl
-             :n-arities (s/* (s/spec ::tail-impl)))))
-
-(s/fdef def-entity
-  :args ::def-entity-args
-  :ret any?)
-
-(def pdf-log (atom nil))
-
-(defn- parse-def-form [args]
-  (as/qwik-conform [{:keys [name tails] :as spec} ::def-entity-args args]
-    (let [qualified-name  (symbol
-                            (c/name (ns-name *ns*))
-                            (c/name name))
-          qualified-kw (keyword qualified-name) ;; faster lookup!
-          ftails (case (first tails)
-                   :single-arity [(second tails)]
-                   :n-arities (second tails))
-          fmap (into {}
-                 (for [{:keys [tail args]} ftails]
-                   (let [k (case (count args)
-                             0 :init
-                             1 :update)]
-                     [k `(fn ~args ~@tail)])))
-          init-spec (assoc fmap
-                      :kw qualified-kw
-                      :name qualified-name)]
-      init-spec)))
-
-(defmacro def-entity [& args]
-  (let [{:keys [name qualified-kw] :as init-spec} (parse-def-form args)]
-    `(do (init-entity ~init-spec)
-         (defn ~name ^GameObject []
-           (find-entity ~qualified-kw)))))
-
-;; ============================================================
-;; much simpler way, just uses def and vars

 (defn init-def
   "Returns nil if the referenced object is destroyed. Maybe that's not a great idea."
@@ -143,17 +23,3 @@
   (let [{:keys [name] :as init-spec} (parse-def-form args)]
     `(let [x# (init-def  ~(update init-spec :name #(list 'quote %)))]
        (def ~name x#))))
-
-;; ============================================================
-;; desired:
-
-(comment
-  ;; try it:
-  (def-entity mr-humms
-    ([] ;; initialize if no connection found
-     (GameObject. "mr-humms"))
-    ([x] ;; then feed into here I guess..?
-     ()))
-  )
-
-


corrected typo - next job is to put /reset behind a resource and then integrate Friend

--- src/toggler/handler.clj
+++ src/toggler/handler.clj
@@ -22,7 +22,7 @@
   (reset! cfg config))

 (defn reset-cfg []
-  (reload-config read-default-config))
+  (reload-config (read-default-config)))

 (defresource status
   :allowed-methods [:get]


Add debug to http/get to show request.

Add debug to http/get to show request.

--- examples/caching_middleware.clj
+++ examples/caching_middleware.clj
@@ -30,7 +30,12 @@

 (defn example [& uri]
   (http/with-additional-middleware [#'wrap-caching-middleware]
-    (http/get (or uri "https://api.github.com"))))
+    (http/get (or uri "https://api.github.com")
+              {
+               :debug true
+               :debug-body true
+               :throw-entire-message? true
+               })))

 ;; Try this out:
 ;;


Simple prototrack adder.

Simple prototrack adder.

--- sonic-jam/src/sonic_jam/core.cljs
+++ sonic-jam/src/sonic_jam/core.cljs
@@ -151,6 +151,51 @@
                                (om/build param-editor {:cursor (get cursor "params") :id id :set-state-ch set-state-ch}))
                      (dom/span #js {:onClick #(go (>! delete-ch cursor))} " delete? ")
                      (dom/span nil "}"))))))
+
+(defn new-id []
+  (let [letters (map char (range 97 123))]
+    (apply str (take 32 (repeatedly #(rand-nth letters))))))
+
+(def style-grey #js {:style #js {:color "#999"}})
+
+(defn track-builder2 [{:keys [cursor id set-state-ch]} owner]
+  (reify
+    om/IInitState
+    (init-state [_]
+      {:state :init})
+    om/IRenderState
+    (render-state [_ state]
+      (let [transition #(om/update-state! owner (fn [s] (merge s %)))
+            set-width #(om/transact!
+                        cursor (fn [s]
+                                 (clj->js
+                                  (conj s {"type" "none"
+                                           "id" (new-id)
+                                           "beats" (repeat % [0])
+                                           "params" {}}))))
+            width-selection (fn [w s]
+                              (dom/span #js {:onClick
+                                             #(do
+                                                (set-width w)
+                                                (transition {:state :init})
+                                                (go (>! set-state-ch id)))} s))]
+        (condp = (:state state)
+          :init (let [width (apply max (map #(count (get % "beats")) cursor))]
+                  (if (= 0 (count cursor))
+                    (dom/p style-grey
+                           (dom/span #js {:onClick #(transition {:state :open})} "{+}"))
+                    (dom/p style-grey
+                           (dom/span #js {:onClick #(transition {:state :open})} "{+")
+                           (width-selection width (str " " width))
+                           (dom/span nil "}"))))
+          :open (dom/p style-grey
+                       (dom/span #js {:onClick #(transition {:state :init})} "{- ")
+                       (width-selection 1 " 1")
+                       (width-selection 2 " 2")
+                       (width-selection 4 " 4")
+                       (width-selection 8 " 8")
+                       (width-selection 16 " 16")
+                       (dom/span nil "}")))))))

 (defn track-builder [{:keys [cursor id set-state-ch]} owner]
   (reify
@@ -259,7 +304,6 @@
                             (map #(dom/option nil %) (om/observe owner (synths))))
                      (dom/span nil "}")))))))

-
 (defn track-view [{:keys [cursor id delete-ch]} owner]
   (reify
     om/IInitState
@@ -332,9 +376,9 @@
                                                                  (repeat id)
                                                                  (repeat (:delete-ch state)))]
                                                 (om/build-all track-view cursors {:state state}))))
-                            (om/build track-builder {:cursor (get cursor "tracks")
-                                                     :id id
-                                                     :set-state-ch (:set-state-ch state)}))))))))
+                            (om/build track-builder2 {:cursor (get cursor "tracks")
+                                                      :id id
+                                                      :set-state-ch (:set-state-ch state)}))))))))

 (defn app-view [cursor _]
   (reify


Delay start of new wave until minis are gone, too

--- desktop/src-common/ds3/main_screen.clj
+++ desktop/src-common/ds3/main_screen.clj
@@ -209,7 +209,7 @@

 (defn check-game-status [screen entities]
   (let [ship (first (filter #(:ship? %) entities))
-        enemies (filter #(:enemy? %) entities)
+        enemies (filter #(or (:enemy? %) (:mini? %)) entities)
         lives (:p1-lives screen)
         p1-score (:p1-level-score screen)
         high-score (if (< (:high-score screen) p1-score) p1-score (:high-score screen))]


Minor cleanup

Minor cleanup

--- planck-cljs/test/planck/setup_eval.cljs
+++ planck-cljs/test/planck/setup_eval.cljs
@@ -1,7 +1,7 @@
 (ns planck.setup-eval
   (:require-macros [cljs.spec.test])
-  (:require [planck.core :refer [eval]]))
+  (:require [planck.core :refer [eval intern]]))

 ;; The cljs.spec.test macros namespace makes use of eval.
 ;; Intern Planck's implementation of eval for use there.
-(planck.core/intern 'cljs.spec.test$macros 'eval eval)+(intern 'cljs.spec.test$macros 'eval eval)


Added call to grant select priviliges during user creation.

--- support/create_user.clj
+++ support/create_user.clj
@@ -4,8 +4,14 @@
 (deps '[[nasa-cmr/cmr-oracle-lib "0.1.0-SNAPSHOT"]]
       :repositories {"releases" "http://devrepo1.dev.echo.nasa.gov/data/dist/projects/echo/mavenrepo/"})

-(require '[cmr.oracle.user :as o])
+(require '[cmr.oracle.user :as o]
+         '[cmr.common.config :as config])

 ;; TODO change the password for different systems

-(o/create-user (o/sys-dba-conn) "METADATA_DB" "METADATA_DB")
+(let [db (o/sys-dba-conn)
+      tablespace ((config/config-value-fn :catalog-rest-tablespace "DEV_52_CATALOG_REST"))
+      from-user ((config/config-value-fn :catalog-rest-user "DEV_52_CATALOG_REST"))
+      to_user ((config/config-value-fn :metadata-db-user "METADATA_DB"))]
+	(o/create-user db "METADATA_DB" "METADATA_DB")
+	(o/grant-select-priviliges db tablespace from-user to_user))


Add losing example.

Add losing example.

--- test/tfe/core_test.cljs
+++ test/tfe/core_test.cljs
@@ -5,6 +5,15 @@
             [tfe.core :refer [next-game place]]))

 (deftest next-game-test
+  (testing "losing"
+    (is (= (next-game :right {:state :playing :board [[ 4  8 16 nil]
+                                                      [16  8  4   2]
+                                                      [ 2  4  8  16]
+                                                      [16  8  4   2]]})
+           {:state :lost :board [[ 2 4 8 16]
+                                 [16 8 4  2]
+                                 [ 2 4 8 16]
+                                 [16 8 4  2]]})))
   (binding [place identity]
     (testing "collapse left"
       (is (= (next-game :left {:state :playing :board [[ 8   8 2 2]
@@ -15,15 +24,6 @@
                                       [16  8   4 nil]
                                       [32 64   4 nil]
                                       [ 4  2 nil nil]]})))
-    (testing "losing"
-      (is (= (next-game :left {:state :playing :board [[ 2 4 8 16]
-                                                       [16 8 4  2]
-                                                       [ 2 4 8 16]
-                                                       [16 8 4  2]]})
-             {:state :lost :board [[ 2 4 8 16]
-                                   [16 8 4  2]
-                                   [ 2 4 8 16]
-                                   [16 8 4  2]]})))
     (testing "winning"
       (is (= (next-game :down {:state :playing :board [[nil nil nil 1024]
                                                        [nil nil nil 1024]


Fix failing test

Fix failing test

--- test/yada/bidi_test.clj
+++ test/yada/bidi_test.clj
@@ -8,7 +8,7 @@
    ;; TODO: These resources should be loaded automatically via a yada ns
    yada.resources.string-resource
    [juxt.iota :refer (given)]
-   #_[yada.bidi :refer (resource-leaf)]
+   yada.bidi
    [bidi.bidi :as bidi :refer (Matched compile-route succeed context)]
    [bidi.ring :refer (make-handler Ring)]
    [ring.mock.request :refer (request)]))


Remove redundant code

Remove redundant code

--- test/yada/core_test.clj
+++ test/yada/core_test.clj
@@ -13,11 +13,6 @@
         handler (make-handler (:handler matched) opts)]
     (let [res (handler (assoc req :route-params (:route-params matched)))]
       (if (d/deferrable? res) @res res))))
-
-#_(get-op-response spec
-                 (mock/request :get "/pets")
-                 :service-available?
-                 #(d/future (Thread/sleep 1000) false))

 (deftest handlers
   (testing "Service Unavailable"


Fix viewport translucency math

Fix viewport translucency math


remove old test

remove old test

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -579,12 +579,6 @@
                          (keys bolt-to-comps))})
        bolts-with-comps))

-(defn benchmark1 []
-  (benchmark spec1 5))
-
-(defn benchmark2 []
-  (benchmark spec2 5))
-
 ;; (repeatedly #(println (fo (first (nugents (medium) spec1)))))
 ;; (repeatedly #(time (println (fo (first (nugents (medium) spec1))))))
 ;; (repeatedly #(println (fo-ps (first (nugents (medium) spec1)))))


+{:synsem {:subcat '()}} to avoid overgeneration

--- test/babel/test/la.cljc
+++ test/babel/test/la.cljc
@@ -52,8 +52,9 @@
                         :sem {:tense :future}}})))))
 (deftest reader1
   (let [spec (let [agreement (atom {:person :3rd :number :sing :gender :masc})]
-               {:slash false ;; TODO: {:slash false} should be part of default spec.
-                :synsem {:agr agreement
+               {:slash false ;; TODO: {:slash false, :synsem {:subcat '()}} should be part of default spec.
+                :synsem {:subcat '()
+                         :agr agreement
                          :sem {:obj :unspec
                                :tense :past
                                :subj {:pred :lui}


Added multiple keyword match to facts

Added multiple keyword match to facts

--- test/compojure/http.clj
+++ test/compojure/http.clj
@@ -19,6 +19,12 @@
   (= (match-route (compile-route route) path)
      {:x "foo"}))

+(fact "Routes can contain the same keyword many times"
+  [[route path] {"/:x/:x/:x"     "/foo/bar/baz"
+                 "/a/:x/b/:x.:x" "/a/foo/b/bar.baz"}]
+  (= (match-route (compile-route route) path)
+     {:x ["foo" "bar" "baz"]}))
+
 (fact "Routes can match wildcards"
   [[route path] {"/*"     "/foo/bar.txt"
                  "/baz/*" "/baz/foo/bar.txt"


negative tests for predicates

negative tests for predicates

--- test/java_time_test.clj
+++ test/java_time_test.clj
@@ -228,9 +228,10 @@
            (j/offset-date-time (j/instant clock) "UTC")))

     (is (= (j/truncate-to (j/offset-date-time clock) :millis)
-          (j/offset-date-time (j/to-java-date clock) "UTC")))
+           (j/offset-date-time (j/to-java-date clock) "UTC")))

     (is (j/offset-date-time? (j/offset-date-time)))
+    (is (not (j/offset-date-time? nil)))

     (j/with-clock (j/system-clock "UTC")
       (is (= (j/offset-date-time 2015)
@@ -265,7 +266,7 @@
            (j/offset-time (j/instant clock) "UTC")))

     (is (= (j/truncate-to (j/offset-time clock) :millis)
-          (j/offset-time (j/to-java-date clock) "UTC")))
+           (j/offset-time (j/to-java-date clock) "UTC")))

     (is (j/offset-time? (j/offset-time (j/zone-id "UTC"))))
     (is (j/offset-time? (j/offset-time +0)))
@@ -317,10 +318,13 @@
             (j/period 0 :months)
             (j/period 0 :days)))

-     (is (j/period? (j/period)))))
+     (is (j/period? (j/period)))
+     (is (not (j/period? nil)))))

 (deftest operations
   (testing "duration"
+    (is (j/duration? (j/duration 1 :days)))
+    (is (not (j/duration? nil)))
     (testing "plus"
       (is (= (j/duration 100000001)
              (j/plus (j/standard-days 1) (j/hours 3) (j/minutes 46) (j/seconds 40) (j/millis 1) (j/nanos 0))
@@ -341,11 +345,13 @@

     (testing "number ops"
       (is (j/zero? (j/duration 0)))
+      (is (not (j/zero? (j/duration 10))))
       (is (= (j/duration 10) (j/abs (j/duration -10))))
       (is (= (j/duration -10) (j/negate (j/duration 10))))
       (is (= (j/duration 10) (j/min (j/duration 10) (j/duration 11) (j/duration 12))))
       (is (= (j/duration 12) (j/max (j/duration 10) (j/duration 11) (j/duration 12))))
-      (is (j/negative? (j/duration -10)))))
+      (is (j/negative? (j/duration -10)))
+      (is (not (j/negative? (j/duration 10))))))

   (testing "period"
     (testing "plus"


Removed midje.parsing.2-to-lexical-maps.fakes/fake as a dependency.

--- test/pointer/t_core.clj
+++ test/pointer/t_core.clj
@@ -1,6 +1,5 @@
 (ns pointer.t-core
   (:require [clojure.zip :as zip]
-            [midje.parsing.2-to-lexical-maps.fakes :refer [fake]]
             [midje.parsing.util.recognizing :refer [start-of-checking-arrow-sequence?]]
             [midje.sweet :refer :all]
             [midje.test-util :refer [at-line]]
@@ -9,6 +8,7 @@
 (defn this-file [line-number]
   ["t_core.clj" line-number])

+
 ;; Throughout this file, file positions are captured outside of
 ;; facts. That's because facts have their own mechanism for file
 ;; position, and I want it to be clear that this is just working with
@@ -16,29 +16,28 @@

-
-
-
-
-
-
-(def line-marker-2 25)
+(defmacro fake [_ _ _]
+  `{:position (line-number-known ~(:line (meta (second &form))))})
+
+
+(def line-marker-2 23)
 (unfinished f)
-(let [fake-on-one-line (fake (f 1) => 33)
+(let [fake-on-one-line (fake (a) => b)
       multiline-with-position-at-first-token (fake

-                                              (f 1)
+                                              (a)

                                               =>

-                                              33)]
+                                              b)]
   (fact "fake, being a one-level macro, knows its file position as a single line"
     (:position fake-on-one-line) => (this-file (+ 2 line-marker-2))
     (:position multiline-with-position-at-first-token) => (this-file (+ 5 line-marker-2))))

+
 (defmacro result-of-second-form [& forms] (second forms))

-(def line-marker-3 (+ line-marker-2 16))
+(def line-marker-3 40)
 (let [fake (result-of-second-form
             "random garbage"
             (fake (f 1) => 33)
@@ -46,12 +45,13 @@
   (fact "Macros within dirt-simple macroexpansions find their correct file position"
     (:position fake) => (this-file (+ 3 line-marker-3))))

+
 (defmacro fake-constructor [& forms]
   `(do
      (fake ~(nth forms 1) => ~(nth forms 3))))

-(def line-marker-4 (+ line-marker-3 13))
+(def line-marker-4 54)
 (let [fake (fake-constructor
                       "random garbage"
                       (f 1) => 33)]


only poll once\!

only poll once\!

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@9715 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/test.clj
+++ acqEngine/src/org/micromanager/test.clj
@@ -4,11 +4,15 @@
            (org.json JSONObject)
            (org.micromanager MMStudioMainFrame)
            (org.micromanager.api DataProcessor))
-  (:use [org.micromanager.mm :only (load-mm gui mmc)]))
+  (:use [org.micromanager.mm :only (edt load-mm gui mmc)]))

 (load-mm (MMStudioMainFrame/getInstance))

 (def acq (.getAcquisitionEngine gui))
+
+(defn print-chan [prefix image]
+  (when (.tags image)
+    (edt (println prefix (.get (.tags image) "Channel")))))

 (defn simple-data-processor
   "Make a DataProcessor whose process method is implemented by
@@ -22,7 +26,7 @@
                (if (.tags img)
                  (let [result (process-function img)]
                    (if (counted? result)
-                     (doseq [image (process-function (.poll this))]
+                     (doseq [image result]
                        (.produce this image))
                      (.produce this result)))
                  (.produce this img))))))
@@ -69,14 +73,10 @@
   "Duplicates channels"
   (simple-data-processor
     (fn [img]
-      (if (= 0 (.get (.tags img) "ChannelIndex"))
         (let [tags (json-clone (.tags img))]
-          (println (.get tags "Channel"))
           (update-tag! tags "ChannelIndex" #(+ 2 %))
           (update-tag! tags "Channel" #(str % "-2"))
-          (println (.get tags "Channel"))
-          [img (TaggedImage. (.pix img) tags)])
-        img))))
+          [img (TaggedImage. (.pix img) tags)]))))

 (defn restart-test []
   (remove-all-image-processors!)


Enable verbosity in dev config

Enable verbosity in dev config

--- env/dev/cljs/cljs_repl_web/config.cljs
+++ env/dev/cljs/cljs_repl_web/config.cljs
@@ -7,4 +7,4 @@
      :base-path base-path
      :core-cache-url (str base-path "/js-cache/core.cljs.cache.aot.json")
      :src-paths [(str base-path "/main.out")]
-     :verbose-repl? false}))
+     :verbose-repl? true}))


Avoid NPE

Avoid NPE

--- modules/xa/src/main/clojure/immutant/xa/transaction.clj
+++ modules/xa/src/main/clojure/immutant/xa/transaction.clj
@@ -24,7 +24,7 @@
 (defn current
   "Return the active transaction"
   []
-  (.getTransaction manager))
+  (and manager (.getTransaction manager)))

 (defn active?
   "True if currently running within a transaction"


[#183] Test type and record constructor and literals

--- priv/clojure/test_clojure/protocols.clj
+++ priv/clojure/test_clojure/protocols.clj
@@ -407,89 +407,89 @@
     (is (thrown? :throw (->TypeToTestHugeFactories 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)))
     (is (thrown? :throw (->TypeToTestHugeFactories 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27)))))

-;; (deftest test-ctor-literals
-;;   (testing "that constructor calls to print-dup'able classes are supported as literals"
-;;     (is (= "Hi" #java.lang.String["Hi"]))
-;;     (is (= 42 #java.lang.Long[42]))
-;;     (is (= 42 #java.lang.Long["42"]))
-;;     (is (= [:a 42] #clojure.lang.MapEntry[:a 42])))
-;;   (testing "that constructor literals are embeddable"
-;;     (is (= 42 #java.lang.Long[#java.lang.String["42"]])))
-;;   (testing "that constructor literals work for deftypes too"
-;;     (is (= (.a (TypeToTestFactory. 42)) (.a #clojure.test-clojure.protocols.TypeToTestFactory[42])))
-;;     (is (compare-huge-types
-;;          (TypeToTestHugeFactories.  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
-;;          #clojure.test-clojure.protocols.TypeToTestHugeFactories[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]))))
-
-;; (defrecord RecordToTestLiterals [a])
-;; (defrecord TestNode [v l r])
-;; (deftype TypeToTestLiterals [a])
-;; (def lang-str "en")
-;; (deftest exercise-literals
-;;   (testing "that ctor literals can be used in common 'places'"
-;;     (is (= (RecordToTestLiterals. ()) #clojure.test-clojure.protocols.RecordToTestLiterals[()]))
-;;     (is (= (.a (TypeToTestLiterals. ())) (.a #clojure.test-clojure.protocols.TypeToTestLiterals[()])))
-;;     (is (= (RecordToTestLiterals. 42) (into #clojure.test-clojure.protocols.RecordToTestLiterals[0] {:a 42})))
-;;     (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))  (RecordToTestLiterals. #clojure.test-clojure.protocols.RecordToTestLiterals[42])))
-;;     (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))  (->RecordToTestLiterals #clojure.test-clojure.protocols.RecordToTestLiterals[42])))
-;;     (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
-;;            #clojure.test-clojure.protocols.RecordToTestLiterals[#clojure.test-clojure.protocols.RecordToTestLiterals[42]]))
-;;     (is (= (TestNode. 1
-;;                       (TestNode. 2
-;;                                  (TestNode. 3
-;;                                             nil
-;;                                             nil)
-;;                                  nil)
-;;                       (TestNode. 4
-;;                                  (TestNode. 5
-;;                                             (TestNode. 6
-;;                                                        nil
-;;                                                        nil)
-;;                                             nil)
-;;                                  (TestNode. 7
-;;                                             nil
-;;                                             nil)))
-;;            #clojure.test-clojure.protocols.TestNode{:v 1
-;;                                                     :l #clojure.test-clojure.protocols.TestNode{:v 2
-;;                                                                                :l #clojure.test-clojure.protocols.TestNode{:v 3 :l nil :r nil}
-;;                                                                                :r nil}
-;;                                                     :r #clojure.test-clojure.protocols.TestNode{:v 4
-;;                                                                                :l #clojure.test-clojure.protocols.TestNode{:v 5
-;;                                                                                :l #clojure.test-clojure.protocols.TestNode{:v 6 :l nil :r nil}
-;;                                                                                :r nil}
-;;                                                                                :r #clojure.test-clojure.protocols.TestNode{:v 7 :l nil :r nil}}})))
-
-;;   (testing "that records and types are evalable"
-;;     (is (= (RecordToTestLiterals. 42) (eval #clojure.test-clojure.protocols.RecordToTestLiterals[42])))
-;;     (is (= (RecordToTestLiterals. 42) (eval #clojure.test-clojure.protocols.RecordToTestLiterals{:a 42})))
-;;     (is (= (RecordToTestLiterals. 42) (eval (RecordToTestLiterals. 42))))
-;;     (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
-;;            (eval #clojure.test-clojure.protocols.RecordToTestLiterals[#clojure.test-clojure.protocols.RecordToTestLiterals[42]])))
-;;     (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
-;;            (eval #clojure.test-clojure.protocols.RecordToTestLiterals[#clojure.test-clojure.protocols.RecordToTestLiterals{:a 42}])))
-;;     (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
-;;            (eval #clojure.test-clojure.protocols.RecordToTestLiterals{:a #clojure.test-clojure.protocols.RecordToTestLiterals[42]})))
-;;     (is (= 42 (.a (eval #clojure.test-clojure.protocols.TypeToTestLiterals[42])))))
-
-;;   (testing "that ctor literals only work with constants or statics"
-;;     (is (thrown? Exception (read-string "#java.util.Locale[(str 'en)]")))
-;;     (is (thrown? Exception (read-string "(let [s \"en\"] #java.util.Locale[(str 'en)])")))
-;;     (is (thrown? Exception (read-string "#clojure.test-clojure.protocols.RecordToTestLiterals{(keyword \"a\") 42}"))))
-
-;;   (testing "that ctors can have whitespace after class name but before {"
-;;     (is (= (RecordToTestLiterals. 42)
-;;            (read-string "#clojure.test-clojure.protocols.RecordToTestLiterals   {:a 42}"))))
-
-;;   (testing "that the correct errors are thrown with malformed literals"
-;;     (is (thrown-with-msg?
-;;           Exception
-;;           #"Unreadable constructor form.*"
-;;           (read-string "#java.util.Locale(\"en\")")))
-;;     (is (thrown-with-msg?
-;;           Exception
-;;           #"Unexpected number of constructor arguments.*"
-;;           (read-string "#java.util.Locale[\"\" \"\" \"\" \"\"]")))
-;;     (is (thrown? Exception (read-string "#java.util.Nachos(\"en\")")))))
+(deftest test-ctor-literals
+  ;; (testing "that constructor calls to print-dup'able classes are supported as literals"
+  ;;   (is (= "Hi" #java.lang.String["Hi"]))
+  ;;   (is (= 42 #java.lang.Long[42]))
+  ;;   (is (= 42 #java.lang.Long["42"]))
+  ;;   (is (= [:a 42] #clojure.lang.MapEntry[:a 42])))
+  ;; (testing "that constructor literals are embeddable"
+  ;;   (is (= 42 #java.lang.Long[#java.lang.String["42"]])))
+  (testing "that constructor literals work for deftypes too"
+    (is (= (.-a (TypeToTestFactory. 42)) (.-a #clojure.test-clojure.protocols.TypeToTestFactory[42])))
+    (is (compare-huge-types
+         (TypeToTestHugeFactories.  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
+         #clojure.test-clojure.protocols.TypeToTestHugeFactories[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]))))
+
+(defrecord RecordToTestLiterals [a])
+(defrecord TestNode [v l r])
+(deftype TypeToTestLiterals [a])
+(def lang-str "en")
+(deftest exercise-literals
+  (testing "that ctor literals can be used in common 'places'"
+    (is (= (RecordToTestLiterals. ()) #clojure.test-clojure.protocols.RecordToTestLiterals[()]))
+    (is (= (.-a (TypeToTestLiterals. ())) (.-a #clojure.test-clojure.protocols.TypeToTestLiterals[()])))
+    (is (= (RecordToTestLiterals. 42) (into #clojure.test-clojure.protocols.RecordToTestLiterals[0] {:a 42})))
+    (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))  (RecordToTestLiterals. #clojure.test-clojure.protocols.RecordToTestLiterals[42])))
+    (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))  (->RecordToTestLiterals #clojure.test-clojure.protocols.RecordToTestLiterals[42])))
+    (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
+           #clojure.test-clojure.protocols.RecordToTestLiterals[#clojure.test-clojure.protocols.RecordToTestLiterals[42]]))
+    (is (= (TestNode. 1
+                      (TestNode. 2
+                                 (TestNode. 3
+                                            nil
+                                            nil)
+                                 nil)
+                      (TestNode. 4
+                                 (TestNode. 5
+                                            (TestNode. 6
+                                                       nil
+                                                       nil)
+                                            nil)
+                                 (TestNode. 7
+                                            nil
+                                            nil)))
+           #clojure.test-clojure.protocols.TestNode{:v 1
+                                                    :l #clojure.test-clojure.protocols.TestNode{:v 2
+                                                                                :l #clojure.test-clojure.protocols.TestNode{:v 3 :l nil :r nil}
+                                                                                :r nil}
+                                                    :r #clojure.test-clojure.protocols.TestNode{:v 4
+                                                                                :l #clojure.test-clojure.protocols.TestNode{:v 5
+                                                                                :l #clojure.test-clojure.protocols.TestNode{:v 6 :l nil :r nil}
+                                                                                :r nil}
+                                                                                :r #clojure.test-clojure.protocols.TestNode{:v 7 :l nil :r nil}}})))
+
+  (testing "that records and types are evalable"
+    (is (= (RecordToTestLiterals. 42) (eval #clojure.test-clojure.protocols.RecordToTestLiterals[42])))
+    (is (= (RecordToTestLiterals. 42) (eval #clojure.test-clojure.protocols.RecordToTestLiterals{:a 42})))
+    (is (= (RecordToTestLiterals. 42) (eval (RecordToTestLiterals. 42))))
+    (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
+           (eval #clojure.test-clojure.protocols.RecordToTestLiterals[#clojure.test-clojure.protocols.RecordToTestLiterals[42]])))
+    (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
+           (eval #clojure.test-clojure.protocols.RecordToTestLiterals[#clojure.test-clojure.protocols.RecordToTestLiterals{:a 42}])))
+    (is (= (RecordToTestLiterals. (RecordToTestLiterals. 42))
+           (eval #clojure.test-clojure.protocols.RecordToTestLiterals{:a #clojure.test-clojure.protocols.RecordToTestLiterals[42]})))
+    (is (= 42 (.-a (eval #clojure.test-clojure.protocols.TypeToTestLiterals[42])))))
+
+  (testing "that ctor literals only work with constants or statics"
+    (is (thrown? :error (read-string "#java.util.Locale[(str 'en)]")))
+    (is (thrown? :error (read-string "(let [s \"en\"] #java.util.Locale[(str 'en)])")))
+    (is (thrown? :error (read-string "#clojure.test-clojure.protocols.RecordToTestLiterals{(keyword \"a\") 42}"))))
+
+  (testing "that ctors can have whitespace after class name but before {"
+    (is (= (RecordToTestLiterals. 42)
+           (read-string "#clojure.test-clojure.protocols.RecordToTestLiterals   {:a 42}"))))
+
+  (testing "that the correct errors are thrown with malformed literals"
+    (is (thrown-with-msg?
+          :error
+          #"Unreadable constructor form.*"
+          (read-string "#java.util.Locale(\"en\")")))
+    (is (thrown-with-msg?
+          :error
+          #"Unexpected number of constructor arguments.*"
+          (read-string "#java.util.Locale[\"\" \"\" \"\" \"\"]")))
+    (is (thrown? :error (read-string "#java.util.Nachos(\"en\")")))))

 ;; (defrecord RecordToTestPrinting [a b])
 ;; (deftest defrecord-printing


Add test for `of-months`

Add test for `of-months`

--- test/tick/api_test.cljc
+++ test/tick/api_test.cljc
@@ -359,7 +359,8 @@
 ;; Periods. Convenience functions to create periods of specific
 ;; units.
 (deftest period-functions-test
-  (is (= (t/of-days 10) (java.time.Period/ofDays 10))))
+  (is (= (t/of-days 10) (java.time.Period/ofDays 10)))
+  (is (= (t/of-months 10) (java.time.Period/ofMonths 10))))

 (deftest predicates-test
   (is (true? (t/clock? (t/clock))))


eliminate unnecessary destructuring

eliminate unnecessary destructuring

--- src/app/cljs/one/sample/view.cljs
+++ src/app/cljs/one/sample/view.cljs
@@ -43,19 +43,17 @@
   (destroy! ($ "#workspace"))
   (append! ($ "#content") (:workspace snippets)))

-(defmethod render :workspace [{:keys [who id content]}]
+(defmethod render :workspace [document]
   (refresh-workspace!)
   (let [workspace ($ "#workspace")
         views     ($ "#content > div")
         editor    ($ "#workspace-editor-field")]
     (deactivate! views)
     (activate! workspace)
-    (editor/launch editor (model/document-session
-                           :who who :id id :content content))))
+    (editor/launch editor (model/session document))))

 (dispatch/react-to #{:document-retrieved}
-                   (fn [_ {:keys [who id content]}]
-                     (render {:state :workspace
-                              :who who :id id :content content})))
+                   (fn [_ d]
+                     (render (assoc d :state :workspace))))

 (dispatch/react-to #{:state-change} (fn [_ m] (render m)))


:sparkles: Make interaction paths size independent of zoom

--- frontend/src/uxbox/main/ui/workspace/shapes/interactions.cljs
+++ frontend/src/uxbox/main/ui/workspace/shapes/interactions.cljs
@@ -94,8 +94,35 @@
     [orig-pos orig-x orig-y dest-pos dest-x dest-y]))

+(mf/defc interaction-marker
+  [{:keys [x y arrow-dir zoom] :as props}]
+  (let [arrow-pdata (case arrow-dir
+                      :right "M -5 0 l 8 0 l -4 -4 m 4 4 l -4 4"
+                      :left "M 5 0 l -8 0 l 4 -4 m -4 4 l 4 4"
+                      [])
+        inv-zoom (/ 1 zoom)]
+    [:*
+      [:circle {:cx 0
+                :cy 0
+                :r 8
+                :stroke "#31EFB8"
+                :stroke-width 2
+                :fill "#FFFFFF"
+                :transform (str
+                             "scale(" inv-zoom ", " inv-zoom ") "
+                             "translate(" (* zoom x) ", " (* zoom y) ")")}]
+      (when arrow-dir
+        [:path {:stroke "#31EFB8"
+                :fill "transparent"
+                :stroke-width 2
+                :d arrow-pdata
+                :transform (str
+                             "scale(" inv-zoom ", " inv-zoom ") "
+                             "translate(" (* zoom x) ", " (* zoom y) ")")}])]))
+
+
 (mf/defc interaction-path
-  [{:keys [orig-shape dest-shape dest-point selected selected?] :as props}]
+  [{:keys [orig-shape dest-shape dest-point selected selected? zoom] :as props}]
   (let [[orig-pos orig-x orig-y dest-pos dest-x dest-y]
         (if dest-shape
           (connect-to-shape orig-shape dest-shape)
@@ -107,67 +134,47 @@
         path ["M" orig-x orig-y "C" (+ orig-x orig-dx) orig-y (+ dest-x dest-dx) dest-y dest-x dest-y]
         pdata (str/join " " path)

-        arrow-path (if (= dest-pos :left)
-                     ["M" (- dest-x 5) dest-y "l 8 0 l -4 -4 m 4 4 l -4 4"]
-                     ["M" (+ dest-x 5) dest-y "l -8 0 l 4 -4 m -4 4 l 4 4"])
-        arrow-pdata (str/join " " arrow-path)]
+        arrow-dir (if (= dest-pos :left) :right :left)]

     (if-not selected?
       [:path {:stroke "#B1B2B5"
               :fill "transparent"
-              :stroke-width 2
+              :stroke-width (/ 2 zoom)
               :d pdata
               :on-mouse-down #(on-mouse-down % orig-shape selected)}]

       [:g {:on-mouse-down #(on-mouse-down % orig-shape selected)}
        [:path {:stroke "#31EFB8"
                :fill "transparent"
-               :stroke-width 2
+               :stroke-width (/ 2 zoom)
                :d pdata}]
-       [:circle {:cx orig-x
-                 :cy orig-y
-                 :r 8
-                 :stroke "#31EFB8"
-                 :stroke-width 2
-                 :fill "#FFFFFF"}]
-       [:circle {:cx dest-x
-                 :cy dest-y
-                 :r 8
-                 :stroke "#31EFB8"
-                 :stroke-width 2
-                 :fill "#FFFFFF"}]
-       [:path {:stroke "#31EFB8"
-               :fill "transparent"
-               :stroke-width 2
-               :d arrow-pdata}]])))
+       [:& interaction-marker {:x orig-x
+                               :y orig-y
+                               :arrow-dir nil
+                               :zoom zoom}]
+       [:& interaction-marker {:x dest-x
+                               :y dest-y
+                               :arrow-dir arrow-dir
+                               :zoom zoom}]])))

 (mf/defc interaction-handle
-  [{:keys [shape selected] :as props}]
+  [{:keys [shape selected zoom] :as props}]
   (let [shape-rect (geom/selection-rect-shape shape)
         handle-x (+ (:x shape-rect) (:width shape-rect))
-        handle-y (+ (:y shape-rect) (/ (:height shape-rect) 2))
-
-        arrow-path ["M" (- handle-x 5) handle-y "l 8 0 l -4 -4 m 4 4 l -4 4"]
-        arrow-pdata (str/join " " arrow-path)]
-
+        handle-y (+ (:y shape-rect) (/ (:height shape-rect) 2))]
     [:g {:on-mouse-down #(on-mouse-down % shape selected)}
-       [:circle {:cx handle-x
-                 :cy handle-y
-                 :r 8
-                 :stroke "#31EFB8"
-                 :stroke-width 2
-                 :fill "#FFFFFF"}]
-       [:path {:stroke "#31EFB8"
-               :fill "transparent"
-               :stroke-width 2
-               :d arrow-pdata}]]))
+     [:& interaction-marker {:x handle-x
+                             :y handle-y
+                             :arrow-dir :right
+                             :zoom zoom}]]))

 (mf/defc interactions
   [{:keys [selected] :as props}]
   (let [data (mf/deref refs/workspace-data)
         local (mf/deref refs/workspace-local)
+        zoom (mf/deref refs/selected-zoom)
         current-transform (:transform local)
         objects (:objects data)
         active-shapes (filter #(first (get-click-interaction %)) (vals objects))
@@ -184,13 +191,15 @@
                                   :orig-shape shape
                                   :dest-shape dest-shape
                                   :selected selected
-                                  :selected? false}])))
+                                  :selected? false
+                                  :zoom zoom}])))

       (if (and draw-interaction-to first-selected)
         [:& interaction-path {:key "interactive"
                               :orig-shape first-selected
                               :dest-point draw-interaction-to
-                              :selected? true}]
+                              :selected? true
+                              :zoom zoom}]

         (for [shape selected-shapes]
           (let [interaction (get-click-interaction shape)
@@ -200,9 +209,11 @@
                                     :orig-shape shape
                                     :dest-shape dest-shape
                                     :selected selected
-                                    :selected? true}]
+                                    :selected? true
+                                    :zoom zoom}]
               (when (not (#{:move :rotate} current-transform))
                 [:& interaction-handle {:key (:id shape)
                                         :shape shape
-                                        :selected selected}])))))]))
-
+                                        :selected selected
+                                        :zoom zoom}])))))]))
+


Import Java classes the Hickey-approved™ way

--- src/boilerpipe_clj/extractors.clj
+++ src/boilerpipe_clj/extractors.clj
@@ -1,6 +1,7 @@
 (ns boilerpipe-clj.extractors
-  (:import de.l3s.boilerpipe.extractors.ArticleExtractor
-           de.l3s.boilerpipe.extractors.DefaultExtractor))
+  (:import (de.l3s.boilerpipe.extractors
+             ArticleExtractor
+             DefaultExtractor)))

 (defonce article-extractor (ArticleExtractor/getInstance))
 (defonce default-extractor (DefaultExtractor/getInstance))


add test for Edward Kim

add test for Edward Kim

--- src/clj/test/cards-identities.clj
+++ src/clj/test/cards-identities.clj
@@ -30,6 +30,37 @@
     (play-from-hand state :corp "Hedge Fund")
     (is (= 13 (:credit (get-corp))) "Has 13 credits")
     (is (= 13 (core/hand-size state :corp)) "Max hand size is 13")))
+
+(deftest edward-kim
+  "Edward Kim - Trash first operation accessed each turn, but not if first one was in Archives"
+  (do-game
+    (new-game
+      (default-corp [(qty "Hedge Fund" 3) (qty "Restructure" 2) (qty "PAD Campaign" 1)])
+      (make-deck "Edward Kim: Humanity's Hammer" [(qty "Eater" 1) (qty "Sure Gamble" 2)]))
+    (play-from-hand state :corp "Hedge Fund")
+    (trash-from-hand state :corp "PAD Campaign")
+    (take-credits state :corp)
+    (run-empty-server state "Archives")
+    (run-empty-server state "HQ")
+    (is (= 2 (count (:discard (get-corp)))) "No operation trashed from HQ; accessed one in Archives first")
+    (take-credits state :runner)
+    (core/move state :corp (find-card "Hedge Fund" (:discard (get-corp))) :hand)
+    (is (= 1 (count (:discard (get-corp)))))
+    (take-credits state :corp)
+    (run-empty-server state "Archives")
+    (run-empty-server state "HQ")
+    (is (= 2 (count (:discard (get-corp)))) "1 operation trashed from HQ; accessed non-operation in Archives first")
+    (take-credits state :runner)
+    (play-from-hand state :corp "Hedge Fund")
+    (take-credits state :corp)
+    (play-from-hand state :runner "Eater")
+    (let [eater (get-in @state [:runner :rig :program 0])]
+      (run-on state "Archives")
+      (card-ability state :runner eater 0) ; pretend to break a sub so no cards in Archives will be accessed
+      (run-successful state)
+      (is (= 3 (count (:discard (get-corp)))))
+      (run-empty-server state "HQ")
+      (is (= 4 (count (:discard (get-corp)))) "1 operation trashed from HQ; accessed non-operation in Archives first"))))

 (deftest haas-bioroid-stronger-together
   "Stronger Together - +1 strength for Bioroid ice"


small fix

small fix

--- src/cljs/salava/page/ui/edit.cljs
+++ src/cljs/salava/page/ui/edit.cljs
@@ -86,10 +86,9 @@
   (let [badge-id (get-in @block-atom [:badge :id] (session/get-in! [:badge-block :badge :id] 0))
         image (get-in @block-atom [:badge :image_file])
         format (:format @block-atom)]
-    (dump @block-atom)
     [:div.form-group
      [:div.col-xs-8
-      [:div.badge-select
+      #_[:div.badge-select
        [:select {:class "form-control"
                  :aria-label "select badge group"
                  :value badge-id


refactor gui

refactor gui

--- src/cljs/triboard/view/panel.cljs
+++ src/cljs/triboard/view/panel.cljs
@@ -11,13 +11,21 @@
 (s/fdef show-scores
   :args (s/tuple #(every? % cst/players)))

+(defn- player->css-style
+  [player]
+  {:class (str "score--" (name player))})
+
+(defn- player->score-text
+  [player score]
+  (str (str/capitalize (name player)) " - " score))
+
 (defn- show-scores
-  [scores player]
+  [scores highlight?]
   (for [p cst/players]
     ^{:key p}
-    [(if (= player p) :div.score--is-current :div.score)
-     {:class (str "score--" (name p))}
-     (str (str/capitalize (name p)) " - " (get scores p))]
+    [(if (highlight? p) :div.score--is-current :div.score)
+     (player->css-style p)
+     (player->score-text p (get scores p))]
     ))

 (defn- top-panel-button
@@ -25,11 +33,14 @@
   [:button.help-button {:on-click on-click} txt])

 (defn show-top-panel
-  [scores player cb]
+  "Show the top panel of the game that contains
+   * The player scores
+   * The main commands"
+  [scores current-player cb]
   [:div.scores
    [top-panel-button #(cb/on-new-game cb) vutils/star]
    [top-panel-button #(cb/on-toogle-help cb) "?"]
-   (show-scores scores player)
+   (show-scores scores #(= % current-player))
    [top-panel-button #(cb/on-restart cb) vutils/circle-arrow]
    [top-panel-button #(cb/on-undo cb) vutils/back-arrow]
    ])