Add and remove stars on demo

Add and remove stars on demo

--- workspaces/src/com/wsscode/pathom/workspaces/graphql/github_demo.cljs
+++ workspaces/src/com/wsscode/pathom/workspaces/graphql/github_demo.cljs
@@ -17,7 +17,7 @@
     [fulcro.client.mutations :as fm]
     [fulcro.client.data-fetch :as df]))

-(defonce indexes (atom {}))
+(defonce indexes (atom {::pc/idents #{::root}}))

 (defmulti resolver-fn pc/resolver-dispatch)
 (def defresolver (pc/resolver-factory resolver-fn indexes))
@@ -32,7 +32,6 @@
      [{:github.user/login "wilkerlucio" :github.repository/name "pathom"}
       {:github.user/login "fulcrologic" :github.repository/name "fulcro"}
       {:github.user/login "fulcrologic" :github.repository/name "fulcro-inspect"}
-      #_ #_ #_
       {:github.user/login "fulcrologic" :github.repository/name "fulcro-css"}
       {:github.user/login "fulcrologic" :github.repository/name "fulcro-spec"}
       {:github.user/login "thheller" :github.repository/name "shadow-cljs"}]}))
@@ -63,21 +62,49 @@
                                 pp/profile-plugin]}))

 (fm/defmutation github/add-star [_]
+  (action [{:keys [state ref]}]
+    (swap! state update-in ref assoc :github.repository/viewer-has-starred true))
   (remote [_] true))

-(fp/defsc GraphqlDemo
-  [this {::keys []}]
+(fm/defmutation github/remove-star [_]
+  (action [{:keys [state ref]}]
+    (swap! state update-in ref assoc :github.repository/viewer-has-starred false))
+  (remote [_] true))
+
+(fp/defsc Repository
+  [this {:github.repository/keys [id name-with-owner viewer-has-starred]}]
   {:initial-state (fn [_]
                     {})
-   :ident         [:github.user/login :github.user/login]
-   :query         [:github.user/id :github.user/name :github.user/login]
+   :ident         [:github.repository/id :github.repository/id]
+   :query         [:github.repository/id :github.repository/name-with-owner :github.repository/viewer-has-starred]
    :css           []
    :css-include   []}
   (dom/div
-    (dom/button {:onClick #(fp/transact! this ['{(github/add-star {:github/input {:github/starrable-id "abc"}})
-                                                 [:client-mutation-id
-                                                  {:starrable
-                                                   [:viewer-has-starred]}]}])} "Add star")))
+    (dom/div name-with-owner)
+    (if viewer-has-starred
+      (dom/button {:onClick #(fp/transact! this [`{(github/remove-star {:github/input {:github/starrable-id ~id}})
+                                                   [:client-mutation-id
+                                                    {:starrable
+                                                     [:viewer-has-starred]}]}])}
+        "Remove star")
+      (dom/button {:onClick #(fp/transact! this [`{(github/add-star {:github/input {:github/starrable-id ~id}})
+                                                   [:client-mutation-id
+                                                    {:starrable
+                                                     [:viewer-has-starred]}]}])}
+        "Add star"))))
+
+(def repository (fp/factory Repository {:keyfn :github.repository/id}))
+
+(fp/defsc GraphqlDemo
+  [this {:keys [demo-repos]}]
+  {:initial-state (fn [_]
+                    {})
+   :ident         (fn [] [::root "singleton"])
+   :query         [{:demo-repos (fp/get-query Repository)}]
+   :css           []
+   :css-include   []}
+  (dom/div
+    (mapv repository demo-repos)))

 (def graphql-demo (fp/factory GraphqlDemo))

@@ -90,7 +117,7 @@
                           (try
                             (let [idx (<? (pcg/load-index github-gql))]
                               (swap! indexes pc/merge-indexes idx)
-                              (df/load app [:github.user/login "wilkerlucio"] GraphqlDemo {:target [:ui/root]}))
+                              (df/load app [::root "singleton"] GraphqlDemo))
                             (catch :default e (js/console.error "Error making index" e)))))

                       :networking


stage 5

stage 5

--- clojure/src/main/resources/clojure/core.clj
+++ clojure/src/main/resources/clojure/core.clj
@@ -702,7 +702,7 @@
        (cat (concat x y) zs))))

 ;;;;;;;;;;;;;;;;at this point all the support for syntax-quote exists;;;;;;;;;;;;;;;;;;;;;;
-(defmacro delay
+#_(defmacro delay
   "Takes a body of expressions and yields a Delay object that will
   invoke the body only the first time it is forced (with force or deref/@), and
   will cache the result and return it on all subsequent force
@@ -711,13 +711,13 @@
   [& body]
     (list 'new 'clojure.lang.Delay (list* `^{:once true} fn* [] body)))

-(defn delay?
+#_(defn delay?
   "returns true if x is a Delay created with delay"
   {:added "1.0"
    :static true}
   [x] (instance? clojure.lang.Delay x))

-(defn force
+#_(defn force
   "If x is a Delay, returns the (possibly cached) value of its expression, else returns x"
   {:added "1.0"
    :static true}
@@ -1088,7 +1088,7 @@
    :added "1.2"}
   [x] (. clojure.lang.Numbers (dec x)))

-(defn unchecked-inc-int
+#_(defn unchecked-inc-int
   "Returns a number one greater than x, an int.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_int_inc ~x)))
@@ -1102,84 +1102,84 @@
    :added "1.0"}
   [x] (. clojure.lang.Numbers (unchecked_inc x)))

-(defn unchecked-dec-int
+#_(defn unchecked-dec-int
   "Returns a number one less than x, an int.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_int_dec ~x)))
    :added "1.0"}
   [x] (. clojure.lang.Numbers (unchecked_int_dec x)))

-(defn unchecked-dec
+#_(defn unchecked-dec
   "Returns a number one less than x, a long.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_dec ~x)))
    :added "1.0"}
   [x] (. clojure.lang.Numbers (unchecked_dec x)))

-(defn unchecked-negate-int
+#_(defn unchecked-negate-int
   "Returns the negation of x, an int.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_int_negate ~x)))
    :added "1.0"}
   [x] (. clojure.lang.Numbers (unchecked_int_negate x)))

-(defn unchecked-negate
+#_(defn unchecked-negate
   "Returns the negation of x, a long.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x] `(. clojure.lang.Numbers (unchecked_minus ~x)))
    :added "1.0"}
   [x] (. clojure.lang.Numbers (unchecked_minus x)))

-(defn unchecked-add-int
+#_(defn unchecked-add-int
   "Returns the sum of x and y, both int.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_add ~x ~y)))
    :added "1.0"}
   [x y] (. clojure.lang.Numbers (unchecked_int_add x y)))

-(defn unchecked-add
+#_(defn unchecked-add
   "Returns the sum of x and y, both long.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_add ~x ~y)))
    :added "1.0"}
   [x y] (. clojure.lang.Numbers (unchecked_add x y)))

-(defn unchecked-subtract-int
+#_(defn unchecked-subtract-int
   "Returns the difference of x and y, both int.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_subtract ~x ~y)))
    :added "1.0"}
   [x y] (. clojure.lang.Numbers (unchecked_int_subtract x y)))

-(defn unchecked-subtract
+#_(defn unchecked-subtract
   "Returns the difference of x and y, both long.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_minus ~x ~y)))
    :added "1.0"}
   [x y] (. clojure.lang.Numbers (unchecked_minus x y)))

-(defn unchecked-multiply-int
+#_(defn unchecked-multiply-int
   "Returns the product of x and y, both int.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_multiply ~x ~y)))
    :added "1.0"}
   [x y] (. clojure.lang.Numbers (unchecked_int_multiply x y)))

-(defn unchecked-multiply
+#_(defn unchecked-multiply
   "Returns the product of x and y, both long.
   Note - uses a primitive operator subject to overflow."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_multiply ~x ~y)))
    :added "1.0"}
   [x y] (. clojure.lang.Numbers (unchecked_multiply x y)))

-(defn unchecked-divide-int
+#_(defn unchecked-divide-int
   "Returns the division of x by y, both int.
   Note - uses a primitive operator subject to truncation."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_divide ~x ~y)))
    :added "1.0"}
   [x y] (. clojure.lang.Numbers (unchecked_int_divide x y)))

-(defn unchecked-remainder-int
+#_(defn unchecked-remainder-int
   "Returns the remainder of division of x by y, both int.
   Note - uses a primitive operator subject to truncation."
   {:inline (fn [x y] `(. clojure.lang.Numbers (unchecked_int_remainder ~x ~y)))
@@ -1484,7 +1484,7 @@
   [^java.util.Map$Entry e]
     (. e (getValue)))

-(defn rseq
+#_(defn rseq
   "Returns, in constant time, a seq of the items in rev (which
   can be a vector or sorted-map), in reverse order. If rev is empty returns nil"
   {:added "1.0"
@@ -1508,7 +1508,7 @@
   [^clojure.lang.Named x]
     (. x (getNamespace)))

-(defmacro locking
+#_(defmacro locking
   "Executes exprs in an implicit do, while holding the monitor of x.
   Will release the monitor of x in all circumstances."
   {:added "1.0"}
@@ -1554,7 +1554,7 @@
         (recur threaded (next forms)))
       x)))

-(defmacro ->>
+#_(defmacro ->>
   "Threads the expr through the forms. Inserts x as the
   last item in the first form, making a list of it if it is not a
   list already. If there are more forms, inserts the first form as the
@@ -5459,7 +5459,7 @@
         (binding [*pending-paths* (conj *pending-paths* path)]
           (clojure.lang.RT/load (.substring path 1)))))))

-(defn compile
+#_(defn compile
   "Compiles the namespace named by the symbol lib into a set of
   classfiles. The source for the lib must be in a proper
   classpath-relative directory. The output files will go into the
@@ -5473,7 +5473,7 @@

 ;;;;;;;;;;;;; nested associative ops ;;;;;;;;;;;

-(defn get-in
+#_(defn get-in
   "Returns the value in a nested associative structure,
   where ks is a sequence of keys. Returns nil if the key
   is not present, or the not-found value if supplied."
@@ -5503,7 +5503,7 @@
     (assoc m k (assoc-in (get m k) ks v))
     (assoc m k v)))

-(defn update-in
+#_(defn update-in
   "'Updates' a value in a nested associative structure, where ks is a
   sequence of keys and f is a function that will take the old value
   and any supplied args and return the new value, and returns a new
@@ -5517,70 +5517,70 @@
      (assoc m k (apply f (get m k) args)))))

-(defn empty?
+#_(defn empty?
   "Returns true if coll has no items - same as (not (seq coll)).
   Please use the idiom (seq x) rather than (not (empty? x))"
   {:added "1.0"
    :static true}
   [coll] (not (seq coll)))

-(defn coll?
+#_(defn coll?
   "Returns true if x implements IPersistentCollection"
   {:added "1.0"
    :static true}
   [x] (instance? clojure.lang.IPersistentCollection x))

-(defn list?
+#_(defn list?
   "Returns true if x implements IPersistentList"
   {:added "1.0"
    :static true}
   [x] (instance? clojure.lang.IPersistentList x))

-(defn set?
+#_(defn set?
   "Returns true if x implements IPersistentSet"
   {:added "1.0"
    :static true}
   [x] (instance? clojure.lang.IPersistentSet x))

-(defn ifn?
+#_(defn ifn?
   "Returns true if x implements IFn. Note that many data structures
   (e.g. sets and maps) implement IFn"
   {:added "1.0"
    :static true}
   [x] (instance? clojure.lang.IFn x))

-(defn fn?
+#_(defn fn?
   "Returns true if x implements Fn, i.e. is an object created via fn."
   {:added "1.0"
    :static true}
   [x] (instance? clojure.lang.Fn x))

-(defn associative?
+#_(defn associative?
  "Returns true if coll implements Associative"
  {:added "1.0"
   :static true}
   [coll] (instance? clojure.lang.Associative coll))

-(defn sequential?
+#_(defn sequential?
  "Returns true if coll implements Sequential"
  {:added "1.0"
   :static true}
   [coll] (instance? clojure.lang.Sequential coll))

-(defn sorted?
+#_(defn sorted?
  "Returns true if coll implements Sorted"
  {:added "1.0"
    :static true}
   [coll] (instance? clojure.lang.Sorted coll))

-(defn counted?
+#_(defn counted?
  "Returns true if coll implements count in constant time"
  {:added "1.0"
    :static true}
   [coll] (instance? clojure.lang.Counted coll))

-(defn reversible?
+#_(defn reversible?
  "Returns true if coll implements Reversible"
  {:added "1.0"
    :static true}
@@ -5606,7 +5606,7 @@
    :added "1.0"}
  *e)

-(defn trampoline
+#_(defn trampoline
   "trampoline can be used to convert algorithms requiring mutual
   recursion without stack consumption. Calls f with supplied args, if
   any. If f returns a fn, calls that fn with no arguments, and
@@ -5640,7 +5640,7 @@
        (when (meta name) (.setMeta v (meta name)))
        v)))

-(defmacro while
+#_(defmacro while
   "Repeatedly executes body while test expression is true. Presumes
   some side-effect will cause test to become false/nil. Returns nil"
   {:added "1.0"}
@@ -5650,7 +5650,7 @@
        ~@body
        (recur))))

-(defn memoize
+#_(defn memoize
   "Returns a memoized version of a referentially transparent function. The
   memoized version of the function keeps a cache of the mapping from arguments
   to results and, when calls with the same arguments are repeated often, has
@@ -5836,20 +5836,20 @@
   "
   {:added "1.0"})

-(defn future?
+#_(defn future?
   "Returns true if x is a future"
   {:added "1.1"
    :static true}
   [x] (instance? java.util.concurrent.Future x))

-(defn future-done?
+#_(defn future-done?
   "Returns true if future f is done"
   {:added "1.1"
    :static true}
   [^java.util.concurrent.Future f] (.isDone f))

-(defmacro letfn
+(defmacro letfn
   "fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)

   Takes a vector of function specs and a body, and generates a set of
@@ -5862,7 +5862,7 @@
                              (map #(cons `fn %) fnspecs)))
            ~@body))

-(defn fnil
+#_(defn fnil
   "Takes a function f, and returns a function that calls f, replacing
   a nil first argument to f with the supplied value x. Higher arity
   versions can replace arguments in the second and third
@@ -5904,167 +5904,6 @@
             (for [mask (map #(dec (bit-shift-left 1 %)) (range 1 (inc max-mask-bits)))
                   shift (range 0 31)]
               [shift mask]))))
-
-#_(defn- case-map
-  "Transforms a sequence of test constants and a corresponding sequence of then
-  expressions into a sorted map to be consumed by case*. The form of the map
-  entries are {(case-f test) [(test-f test) then]}."
-  [case-f test-f tests thens]
-  (into1 (sorted-map)
-    (zipmap (map case-f tests)
-            (map vector
-              (map test-f tests)
-              thens))))
-
-#_(defn- fits-table?
-  "Returns true if the collection of ints can fit within the
-  max-table-switch-size, false otherwise."
-  [ints]
-  (< (- (apply max (seq ints)) (apply min (seq ints))) max-switch-table-size))
-
-#_(defn- prep-ints
-  "Takes a sequence of int-sized test constants and a corresponding sequence of
-  then expressions. Returns a tuple of [shift mask case-map switch-type] where
-  case-map is a map of int case values to [test then] tuples, and switch-type
-  is either :sparse or :compact."
-  [tests thens]
-  (if (fits-table? tests)
-    ; compact case ints, no shift-mask
-    [0 0 (case-map int int tests thens) :compact]
-    (let [[shift mask] (or (maybe-min-hash (map int tests)) [0 0])]
-      (if (zero? mask)
-        ; sparse case ints, no shift-mask
-        [0 0 (case-map int int tests thens) :sparse]
-        ; compact case ints, with shift-mask
-        [shift mask (case-map #(shift-mask shift mask (int %)) int tests thens) :compact]))))
-
-#_(defn- merge-hash-collisions
-  "Takes a case expression, default expression, and a sequence of test constants
-  and a corresponding sequence of then expressions. Returns a tuple of
-  [tests thens skip-check-set] where no tests have the same hash. Each set of
-  input test constants with the same hash is replaced with a single test
-  constant (the case int), and their respective thens are combined into:
-  (condp = expr
-    test-1 then-1
-    ...
-    test-n then-n
-    default).
-  The skip-check is a set of case ints for which post-switch equivalence
-  checking must not be done (the cases holding the above condp thens)."
-  [expr-sym default tests thens]
-  (let [buckets (loop [m {} ks tests vs thens]
-                  (if (and ks vs)
-                    (recur
-                      (update-in m [(clojure.lang.Util/hash (first ks))] (fnil conj []) [(first ks) (first vs)])
-                      (next ks) (next vs))
-                    m))
-        assoc-multi (fn [m h bucket]
-                      (let [testexprs (apply concat bucket)
-                            expr `(condp = ~expr-sym ~@testexprs ~default)]
-                        (assoc m h expr)))
-        hmap (reduce1
-               (fn [m [h bucket]]
-                 (if (== 1 (count bucket))
-                   (assoc m (ffirst bucket) (second (first bucket)))
-                   (assoc-multi m h bucket)))
-               {} buckets)
-        skip-check (->> buckets
-                     (filter #(< 1 (count (second %))))
-                     (map first)
-                     (into1 #{}))]
-    [(keys hmap) (vals hmap) skip-check]))
-
-#_(defn- prep-hashes
-  "Takes a sequence of test constants and a corresponding sequence of then
-  expressions. Returns a tuple of [shift mask case-map switch-type skip-check]
-  where case-map is a map of int case values to [test then] tuples, switch-type
-  is either :sparse or :compact, and skip-check is a set of case ints for which
-  post-switch equivalence checking must not be done (occurs with hash
-  collisions)."
-  [expr-sym default tests thens]
-  (let [hashcode #(clojure.lang.Util/hash %)
-        hashes (into1 #{} (map hashcode tests))]
-    (if (== (count tests) (count hashes))
-      (if (fits-table? hashes)
-        ; compact case ints, no shift-mask
-        [0 0 (case-map hashcode identity tests thens) :compact]
-        (let [[shift mask] (or (maybe-min-hash hashes) [0 0])]
-          (if (zero? mask)
-            ; sparse case ints, no shift-mask
-            [0 0 (case-map hashcode identity tests thens) :sparse]
-            ; compact case ints, with shift-mask
-            [shift mask (case-map #(shift-mask shift mask (hashcode %)) identity tests thens) :compact])))
-      ; resolve hash collisions and try again
-      (let [[tests thens skip-check] (merge-hash-collisions expr-sym default tests thens)
-            [shift mask case-map switch-type] (prep-hashes expr-sym default tests thens)
-            skip-check (if (zero? mask)
-                         skip-check
-                         (into1 #{} (map #(shift-mask shift mask %) skip-check)))]
-        [shift mask case-map switch-type skip-check]))))
-
-
-#_(defmacro case
-  "Takes an expression, and a set of clauses.
-
-  Each clause can take the form of either:
-
-  test-constant result-expr
-
-  (test-constant1 ... test-constantN)  result-expr
-
-  The test-constants are not evaluated. They must be compile-time
-  literals, and need not be quoted.  If the expression is equal to a
-  test-constant, the corresponding result-expr is returned. A single
-  default expression can follow the clauses, and its value will be
-  returned if no clause matches. If no default expression is provided
-  and no clause matches, an IllegalArgumentException is thrown.
-
-  Unlike cond and condp, case does a constant-time dispatch, the
-  clauses are not considered sequentially.  All manner of constant
-  expressions are acceptable in case, including numbers, strings,
-  symbols, keywords, and (Clojure) composites thereof. Note that since
-  lists are used to group multiple constants that map to the same
-  expression, a vector can be used to match a list if needed. The
-  test-constants need not be all of the same type."
-  {:added "1.2"}
-
-  [e & clauses]
-  (let [ge (with-meta (gensym) {:tag Object})
-        default (if (odd? (count clauses))
-                  (last clauses)
-                  `(throw (IllegalArgumentException. (str "No matching clause: " ~ge))))]
-    (if (> 2 (count clauses))
-      `(let [~ge ~e] ~default)
-      (let [pairs (partition 2 clauses)
-            assoc-test (fn assoc-test [m test expr]
-                         (if (contains? m test)
-                           (throw (IllegalArgumentException. (str "Duplicate case test constant: " test)))
-                           (assoc m test expr)))
-            pairs (reduce1
-                       (fn [m [test expr]]
-                         (if (seq? test)
-                           (reduce1 #(assoc-test %1 %2 expr) m test)
-                           (assoc-test m test expr)))
-                       {} pairs)
-            tests (keys pairs)
-            thens (vals pairs)
-            mode (cond
-                   (every? #(and (integer? %) (<= Integer/MIN_VALUE % Integer/MAX_VALUE)) tests)
-                   :ints
-                   (every? keyword? tests)
-                   :identity
-                   :else :hashes)]
-        (condp = mode
-          :ints
-          (let [[shift mask imap switch-type] (prep-ints tests thens)]
-            `(let [~ge ~e] (case* ~ge ~shift ~mask ~default ~imap ~switch-type :int)))
-          :hashes
-          (let [[shift mask imap switch-type skip-check] (prep-hashes ge default tests thens)]
-            `(let [~ge ~e] (case* ~ge ~shift ~mask ~default ~imap ~switch-type :hash-equiv ~skip-check)))
-          :identity
-          (let [[shift mask imap switch-type skip-check] (prep-hashes ge default tests thens)]
-            `(let [~ge ~e] (case* ~ge ~shift ~mask ~default ~imap ~switch-type :hash-identity ~skip-check))))))))
-

 ;; redefine reduce with internal-reduce
 (defn reduced


add exception-processing for :future

add exception-processing for :future

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -203,7 +203,7 @@
                  " " (get-string-1 (get-in word '(:b)))))

      ;; TODO: all of the rules that handle exceptions should be removed:
-     ;; exceptions are dealt with at compile-time now, via italianverbs.lexicon.italiano/exception-generator
+     ;; exceptions are dealt with at compile-time now, via babel.italiano.morphology/exception-generator

      ;; handle lexical exceptions (plural feminine adjectives):
      (and
@@ -1558,6 +1558,49 @@
                                            :agr {:number :plur
                                                  :person :3rd}}})}

+                            ;; 3. future-tense exceptions
+                            {:path [:italiano :future :1sing]
+                             :merge-fn
+                             (fn [val]
+                               {:italiano {:infl :future
+                                           :italiano (get-in val [:italiano :future :1sing] :nothing)
+                                           :agr {:number :sing
+                                                 :person :1st}}})}
+                            {:path [:italiano :future :2sing]
+                             :merge-fn
+                             (fn [val]
+                               {:italiano {:infl :future
+                                           :italiano (get-in val [:italiano :future :2sing] :nothing)
+                                           :agr {:number :sing
+                                                 :person :2nd}}})}
+                            {:path [:italiano :future :3sing]
+                             :merge-fn
+                             (fn [val]
+                               {:italiano {:infl :future
+                                           :italiano (get-in val [:italiano :future :3sing] :nothing)
+                                           :agr {:number :sing
+                                                 :person :3rd}}})}
+                            {:path [:italiano :future :1plur]
+                             :merge-fn
+                             (fn [val]
+                               {:italiano {:infl :future
+                                           :italiano (get-in val [:italiano :future :1plur] :nothing)
+                                           :agr {:number :plur
+                                                 :person :1st}}})}
+                            {:path [:italiano :future :2plur]
+                             :merge-fn
+                             (fn [val]
+                               {:italiano {:infl :future
+                                           :italiano (get-in val [:italiano :future :2plur] :nothing)
+                                           :agr {:number :plur
+                                                 :person :2nd}}})}
+                            {:path [:italiano :future :3plur]
+                             :merge-fn
+                             (fn [val]
+                               {:italiano {:infl :future
+                                           :italiano (get-in val [:italiano :future :3plur] :nothing)
+                                           :agr {:number :plur
+                                                 :person :3rd}}})}
                             ;; adjectives
                             {:path [:italiano :masc :plur]
                              :merge-fn


Restore *ns* after loading libs

Restore *ns* after loading libs

--- core/data/core.clj
+++ core/data/core.clj
@@ -3043,7 +3043,8 @@
         (printf "(joker.core/load \"%s\")\n" path))
       (check-cyclic-dependency path)
       (when-not (= path (first *pending-paths*))
-        (binding [*pending-paths* (conj *pending-paths* path)]
+        (binding [*pending-paths* (conj *pending-paths* path)
+                  *ns* *ns*]
           (load-file path))))))

 (defn get-in


remove direct-messages section for now

remove direct-messages section for now

--- src/chat/client/views/sidebar.cljs
+++ src/chat/client/views/sidebar.cljs
@@ -85,14 +85,15 @@
                  (map (fn [tag]
                         (dom/div nil (om/build tag-view tag)))))))

-        (dom/h2 nil "Direct Messages")
-        (apply dom/div #js {:className "users"}
-          (->> (@store/app-state :users)
-               vals
-               (remove (fn [user] (= (get-in @store/app-state [:session :user-id]) (user :id))))
-               (map (fn [user]
-                      (dom/div nil
-                        (om/build user-view user))))))
+        (comment
+          (dom/h2 nil "Direct Messages")
+          (apply dom/div #js {:className "users"}
+            (->> (@store/app-state :users)
+                 vals
+                 (remove (fn [user] (= (get-in @store/app-state [:session :user-id]) (user :id))))
+                 (map (fn [user]
+                        (dom/div nil
+                          (om/build user-view user)))))))

         (dom/h2 nil "Recommended")
         (apply dom/div #js {:className "recommended"}


Fix test

Fix test

--- test/caesium/crypto/sign_test.clj
+++ test/caesium/crypto/sign_test.clj
@@ -43,7 +43,8 @@
           (s/verify pk message
                     (s/sign ss message)))))
   (testing "Will not verify arbitrary signature"
-    (is (thrown-with-msg? java.lang.RuntimeException #"^signature was forged or corrupted$"
-                          (let [{pk :public ss :secret} (s/generate-signing-keys)
-                                other-sig (s/sign ss message)]
-                            (s/verify public message other-sig))))))
+    (is (thrown-with-msg?
+         RuntimeException #"^Signature validation failed$"
+         (let [{pk :public sk :secret} (s/generate-signing-keys)
+               other-sig (s/sign sk message)]
+           (s/verify public message other-sig))))))


clean tests

clean tests

--- test/cljs/triboard/core_test.cljs
+++ test/cljs/triboard/core_test.cljs
@@ -38,11 +38,6 @@
   [score]
   (transduce (map second) + score))

-(defn check-spec-test
-  [spec-res]
-  (let [res (stest/summarize-results spec-res)]
-    (= (:total res) (:check-passed res))))
-

 ;; ----------------------------------------------------------------------------
 ;; Generators
@@ -62,19 +57,6 @@
 ;; ----------------------------------------------------------------------------
 ;; Property based tests
 ;; ----------------------------------------------------------------------------
-
-#_(
-    (deftest board-test
-      (is (check-spec-test (stest/check `board/empty-cells)))
-      (is (check-spec-test (stest/check `board/to-seq))))
-
-    (deftest scores-test
-      (is (check-spec-test (stest/check `scores/update-scores))))
-
-    (deftest move-test
-      (is (check-spec-test (stest/check `move/all-available-moves)))
-      (is (check-spec-test (stest/check `move/apply-conversion))))
-    )

 (defn valid-game-transition?
   [old-game new-game move]


Mix calling style a bit in tests

Mix calling style a bit in tests

--- test/reagenttest/testmonitor.cljs
+++ test/reagenttest/testmonitor.cljs
@@ -137,15 +137,13 @@
     (let [a (rv/atom 0)
           f (fn [x] (+ x @a))
           b (monitor f 1)
-          c (monitor f -1)
-          d (run! [@b @c])]
+          d (run! [@b @(monitor f -1)])]
       (is (= @d [1 -1]))
       (dispose d))
     (let [a (rv/atom 0)
           f (fn [x] (+ x @a))
-          b (monitor f 1)
           c (monitor f -1)
-          d (run! [@b @c])
+          d (run! [@(monitor f 1) @c])
           res (rv/atom 0)]
       (is (= @d [1 -1]))
       (let [e (run! (reset! res @d))]


fix #117; use safeLoadMany instead of loadMany

--- src/adzerk/boot_reload/reload.cljs
+++ src/adzerk/boot_reload/reload.cljs
@@ -3,6 +3,7 @@
    [clojure.string          :as string]
    [goog.Uri                :as guri]
    [goog.async.DeferredList :as deferred-list]
+   [goog.html.legacyconversions :as conv]
    [goog.net.jsloader       :as jsloader]))

 (defn- page-uri []
@@ -43,15 +44,16 @@

 (defn- reload-js [changed {:keys [on-jsload]
                            :or {on-jsload identity}}]
-  (let [js-files (filter #(ends-with? % ".js") changed)]
+  (let [js-files (filter #(ends-with? % ".js") changed)
+        to-safe-url (fn to-safe-url [js-file]
+                      (-> js-file guri/parse .makeUnique .toString conv/trustedResourceUrlFromString))]
     (when (seq js-files)
-      (-> #(-> % guri/parse .makeUnique)
-        (map js-files)
-        clj->js
-        (jsloader/loadMany #js {:cleanupWhenDone true})
-        (.addCallbacks
-          (fn [& _] (on-jsload))
-          (fn [e] (.error js/console "Load failed:" (.-message e)))))
+      (-> (map to-safe-url js-files)
+          clj->js
+          (jsloader/safeLoadMany #js {:cleanupWhenDone true})
+          (.addCallbacks
+           (fn [& _] (on-jsload))
+           (fn [e] (.error js/console "Load failed:" (.-message e)))))
       (when (aget js/window "jQuery")
         (.trigger (js/jQuery js/document) "page-load")))))


Fix indentation.

Fix indentation.

--- src/afterglow/fixtures/chauvet.clj
+++ src/afterglow/fixtures/chauvet.clj
@@ -20,5 +20,4 @@
             :6-channel {:channels [(chan/color 1 :red) (chan/color 2 :green) (chan/color 3 :blue)
                                    (chan/color 4 :amber) (chan/color 5 :white) (chan/color 6 :uv "UV")]})
           :name "Chauvet SlimPAR Hex 3 IRC"
-          :mode mode))
-  )
+          :mode mode)))


New functions: insert-branch-for-commit insert-branches-for-commit and insert-changed-files-and-branches

--- src/arachnida/git_data_fetcher.clj
+++ src/arachnida/git_data_fetcher.clj
@@ -39,11 +39,28 @@
         (println "        Fetching all branches: " dirname)
         (git-interface/fetch-all (repo-url->directory-name repository))))

-
 (defn insert-changed-files
     [db commit-id changed-files]
     (doseq [changed-file changed-files]
         (db-interface/insert-changed-file db commit-id changed-file)))
+
+(defn insert-branch-for-commit
+    [transaction commit-id branch]
+    (let [branch-name (commits-stat/update-branch-name branch)]
+         (db-interface/insert-branch-for-commit transaction commit-id branch-name)))
+
+(defn insert-branches-for-commit
+    [transaction commit-id branches]
+    (doseq [branch branches]
+        (insert-branch-for-commit transaction commit-id branch)))
+
+(defn insert-changed-files-and-branches
+    [transaction product repository commit-sha changed-files branches]
+    (let [commit-id (db-interface/read-commit-id transaction (:id product) (:id repository) commit-sha)]
+                    (if (not commit-id)
+                        (println "Warning: no ID for commit " commit-sha))
+                    (insert-changed-files transaction commit-id changed-files)
+                    (insert-branches-for-commit transaction commit-id branches)))

 (defn revision-list
     [product repository repo commits-stat]
@@ -62,13 +79,12 @@
                   files-changed (or (:files-changed stat) 0)
                   insertions    (or (:insertions stat) 0)
                   deletions     (or (:deletions stat) 0)]
-                (doseq [branch branches]
-                    (let [branch-name (commits-stat/update-branch-name branch)]
-                        (db-interface/insert-commit transaction (:id product) (:id repository)
-                                               branch-name commit-sha message
-                                               author date files-changed insertions deletions)
-                        (insert-changed-files transaction
-                                    (db-interface/read-commit-id transaction (:id product) (:id repository) branch-name commit-sha) changed-files)))
+                  (if (not stat)
+                      (println "Warning: no stat info for commit " commit-sha "(" author message date branches ")"))
+                  (db-interface/insert-commit transaction (:id product) (:id repository)
+                                              commit-sha message
+                                              author date files-changed insertions deletions)
+                  (insert-changed-files-and-branches transaction product repository commit-sha changed-files branches)
              )))))

 (defn process-repository


Make a nil group id give nil, not a weird map

--- src/braid/core/server/db/group.clj
+++ src/braid/core/server/db/group.clj
@@ -22,8 +22,8 @@

 (defn group-by-id
   [group-id]
-  (-> (d/pull (db/db) group-pull-pattern [:group/id group-id])
-      db->group))
+  (some-> (d/pull (db/db) group-pull-pattern [:group/id group-id])
+          db->group))

 (defn group-by-slug
   [group-slug]


added space to predicate.

added space to predicate.

--- src/clj/forma/hadoop/predicate.clj
+++ src/clj/forma/hadoop/predicate.clj
@@ -21,6 +21,7 @@

 (defmapcatop [sample [res]]
   [& args] (range (pixels-at-res res)))
+
 (defmapcatop [line [res]]
   [& args] (range (pixels-at-res res)))


Fixing some bit

Fixing some bit

--- src/clj_fuzzy/daitch_mokotoff.cljc
+++ src/clj_fuzzy/daitch_mokotoff.cljc
@@ -13,8 +13,8 @@
 (def ^:private table
   [[#"^(AI|AJ|AY)" \0   \1   nil]
    [#"^AU"         \0   \7   nil]
-   [#"^Ą"          nil nil [\6 nil]]
-   [#"^A"          \0   nil nil]
+   [#"^Ą"          nil  nil  [\6 nil]]
+   [#"^A"          \0   nil  nil]
    [#"^B"          \7   \7   \7]])

 ;; Utilities
@@ -35,9 +35,9 @@
 (defn apply-rule
   "Apply a single [rule] to the current [code]."
   [code rule]
-  (clojure.string/replace code (first rule) (or (second rule) "")))
+  (clojure.string/replace code (first rule) (str (or (second rule) ""))))

-;; TODO: treat -> process -> take 6 -> pad
+;; TODO: treat -> process (several options) -> take 6 -> pad
 (defn process
   "Compute the Daitch-Mokotoff soundex code for the given [word]."
   [word]


Finished browser evaluator code.

Finished browser evaluator code.

--- src/cljs/clojure/browser/repl.cljs
+++ src/cljs/clojure/browser/repl.cljs
@@ -46,7 +46,7 @@
           inbound-connection  (net/xhr-connection)
           outbound-connection (net/xhr-connection)]
       (net/register-service repl-connection
-                            :post-results
+                            :send-result
                             (partial send-result
                                      outbound-connection))
       (event/listen outbound-connection
@@ -56,7 +56,9 @@
       (event/listen inbound-connection
                     :success
                     (fn [e]
-                      (evaluate-javascript
+                      (net/transmit
+                       repl-connection
+                       :evaluate-javascript
                        (.getResponseText e/currentTarget
                                          ())))))
     (js/alert "No 'xpc' param provided to child iframe.")))


enrich url regex, add host dependent connection

--- src/cljs/link_collective/core.cljs
+++ src/cljs/link_collective/core.cljs
@@ -19,6 +19,10 @@

 (enable-console-print!)

+(def uri (goog.Uri. js/document.URL))
+
+(def ssl? (= (.getScheme uri) "https"))
+
 ;; fire up repl
 #_(do
     (ns weasel.startup)
@@ -55,10 +59,8 @@
                             "master"))))

-(def url-regexp #"(https?|ftp)://[a-z0-9-]+(\.[a-z0-9-]+)+(/[\w-]+)*(/[\w-\.]+)*")
-
-
-(def app-state (atom nil))
+(def url-regexp #"(https?|ftp)://[a-z0-9-]+(\.[a-z0-9-]+)+(/[\w-?#]+)*(/[\w-\.]+)*")
+

 (defn add-post [stage e]
   (let [post-id (uuid)
@@ -143,7 +145,14 @@

   (<! (timeout 500))

-  (<! (s/connect! stage "ws://localhost:8080/geschichte/ws"))
+  (<! (s/connect!
+       stage
+       (str
+        (if ssl?  "wss://" "ws://")
+        (.getDomain uri)
+        ":"
+        8080 #_(.getPort uri)
+        "/geschichte/ws")))

   (defn collection-view [app owner]
@@ -154,7 +163,7 @@
          :add-post (partial add-post stage)
          :add-comment (partial add-comment stage)})
       om/IRenderState
-      (render-state [this {:keys [selected-entry] :as state}]
+      (render-state [this {:keys [selected-entries add-comment add-post] :as state}]
         (om/build
          main-view
          app
@@ -170,7 +179,6 @@

 (comment
   (def eve-data (get-in @stage [:volatile :val-atom]))
-

   (let [db (get-in @eve-data ["eve@polyc0l0r.net"
                                      #uuid "b09d8708-352b-4a71-a845-5f838af04116"
@@ -254,6 +262,4 @@
                                #uuid "b09d8708-352b-4a71-a845-5f838af04116"
                                "master"])))

-
-
 )


Minor: comment

Minor: comment

--- src/cljs/mandelbrot_cljs/core.cljs
+++ src/cljs/mandelbrot_cljs/core.cljs
@@ -11,8 +11,9 @@

 (def initial-rendering-data
   {:scale          350 ; How many pixels a distance of 1 in the complex plane takes up
-   :x0             -3
-   :y0             1.2})
+   :x0             -3 ; the x co-ordinate of the top-left pixel in the canvase
+   :y0             1.2 ; the y co-ordinate of the top-left pixel in the canvase
+   })

 (defonce app-state (atom {:escape-radius 10000
                           :rendering-data initial-rendering-data}))
@@ -34,6 +35,10 @@
   (aset overlay-canvas "height"(.-innerHeight js/window)))

 (defn render-mandelbrot!
+  "Iterate over every pixel in the canvas, rendering the mandelbrot
+  set at the specified scale. Uses a javascript function (in resources/public/js/fractal-maths.js)
+  for the hard maths, because clojurescript just wasn't cutting it speed wise (you really want local
+  variables for this kind of thing - I got it to be only ~10 times slower using the >> and << macros)"
   [{escape-radius                          :escape-radius
     {:keys [scale x0 y0] :as render-state} :rendering-data}]

@@ -46,7 +51,6 @@

         width                 (.-width canvas)
         height                (.-height canvas)
-
         idata                 (.createImageData context width height)
         data                  (.-data idata)

@@ -57,12 +61,10 @@
      (forloop
       [(y 0) (< y height) (inc y)]

-
       (let [real       (+ (/ x scale) x0)
             imaginary  (- (/ y scale) y0)
             iterations (js/mandelbrot_smoothed_iteration_count escape-radius-squared max-iterations real imaginary)
             intensity  (* 255 (/ iterations max-iterations))
-
             data-index (* 4 (+ x (* y width)))]

         (aset data data-index intensity)
@@ -73,14 +75,6 @@
     (.putImageData context idata 0 0)

     (.log js/console "Done in: " (int (* 1000 (/ (* height width)  (- (.getTime (js/Date.)) start)))) "px/s")))
-
-(set! (.-onresize js/window) (fn [] (render-mandelbrot! @app-state)))
-
-(add-watch app-state :state-changed
-           (fn [_ _ old-state new-state]
-             (when-not (= (:rendering-data old-state)
-                          (:rendering-data new-state))
-               (render-mandelbrot! new-state))))

 (defn add-overlay-rectangle!
   "Adds a rectangle to the overlay canvas (and optionally clears all other rectangles)"
@@ -167,6 +161,13 @@

 (set! (.-onmouseup overlay-canvas) handle-mouseup)

+(set! (.-onresize js/window) (fn [] (render-mandelbrot! @app-state)))
+
+(add-watch app-state :state-changed
+           (fn [_ _ old-state new-state]
+             (when-not (= (:rendering-data old-state)
+                          (:rendering-data new-state))
+               (render-mandelbrot! new-state))))

 (render-mandelbrot! @app-state)


Wordpress badge embed fix

Wordpress badge embed fix

--- src/cljs/salava/core/ui/share.cljs
+++ src/cljs/salava/core/ui/share.cljs
@@ -186,8 +186,7 @@

 (defn wordpress-embed [badge_name image_file url issuer]
   (let [site-url (session/get :site-url)]
-    (str "

"badge_name"

"issuer"

")))
-
+    (str "

"badge_name"

"issuer"

")))

 (defn share-buttons-element [url title public? is-badge? link-or-embed-atom image-file certification]


fix typos in initialization of past-participle irregulars

--- src/babel/francais/morphology.cljc
+++ src/babel/francais/morphology.cljc
@@ -170,13 +170,11 @@
            (verbs/imperfect word)

            (= (get-in word '(:infl)) :past-p)
-           (let [number-and-person (verbs/number-and-person number person)
-                 infl (get-in word [:infl])]
-             (cond (and number-and-person
-                        (get-in word [infl number-and-person]))
-                   (get-in word [infl number-and-person])
-                   true
-                   (conjugate (get-in word [:français]) word)))
+           (cond (get-in word [:past-participle])
+                 (get-in word [:past-participle])
+                 true
+                 (conjugate (get-in word [:français]) word))
+
            (and
             (get-in word '(:a))
             (get-in word '(:b)))
@@ -345,11 +343,11 @@
                                        lexemes)))
                            [
                             ;; 1. past-tense exceptions
-                            {:path [:français :past]
-                             :merge-fn
-                             (fn [val]
-                               {:français {:infl :past
-                                           :français (get-in val [:français :past] :nothing)}})}
+                            {:path [:français :past-participle]
+                             :merge-fn
+                             (fn [val]
+                               {:français {:infl :past-p
+                                           :français (get-in val [:français :past-participle] :nothing)}})}

                             ;; 2. present-tense exceptions
                             {:path [:français :present :1sing]


CMR-1694: Minor modification to a comment.

--- virtual-product-app/src/cmr/virtual_product/services/virtual_product_service.clj
+++ virtual-product-app/src/cmr/virtual_product/services/virtual_product_service.clj
@@ -127,11 +127,11 @@
       ;; granule is present in the virtual product queue and is not yet consumed. The exception will
       ;; cause the event to be put back in the queue. The event will be retried until the ingest
       ;; event is consumed.
-      ;; Note that the existence of a delete event for the virtual granule means that the real
-      ;; granule exists in the database (otherwise corresponding delete request for real granule
-      ;; would fail with 404 and the delete event for the virtual granule would never be put on
-      ;; the virtual product queue to begin with). Which in turn means that ingest event
-      ;; corresponding to the granule has been created in the past (either recent past or
+      ;; Note that the existence of a delete event for the virtual granule means that the
+      ;; corresponding real granule exists in the database (otherwise corresponding delete request
+      ;; for real granule would fail with 404 and the delete event for the virtual granule would
+      ;; never be put on the virtual product queue to begin with). Which in turn means that ingest
+      ;; event corresponding to the granule has been created in the past (either recent past or
       ;; distant past) and that event has to to consumed before the delete event can be consumed
       ;; off the queue.
       (= status 404) (errors/internal-error!


fix 6/30 bug in EN

fix 6/30 bug in EN

--- resources/duckling/rules/en.time.clj
+++ resources/duckling/rules/en.time.clj
@@ -429,7 +429,7 @@
   (parse-dmy (nth (:groups %1) 2) (second (:groups %1)) (first (:groups %1)) true)

   "mm/dd"
-  #"(0?\d|10|11|12)/([012]?\d|30|31)"
+  #"(0?\d|10|11|12)/(30|31|[012]?\d)"
   (parse-dmy (second (:groups %1)) (first (:groups %1)) nil true)


docker client cleanup

docker client cleanup

--- src/clj/swarmpit/docker/client.clj
+++ src/clj/swarmpit/docker/client.clj
@@ -2,7 +2,7 @@
   (:refer-clojure :exclude [get])
   (:require [clojure.java.shell :as shell]
             [clojure.string :as string]
-            [cheshire.core :refer [parse-string]]))
+            [cheshire.core :refer [parse-string generate-string]]))

 (def ^:private api-version "v1.24")
 (def ^:private base-cmd ["curl" "--unix-socket" "/var/run/docker.sock" "-w" "%{http_code}"])
@@ -26,7 +26,7 @@
   [json]
   (if (nil? json)
     []
-    ["-d" json]))
+    ["-d" (generate-string json {:pretty true})]))

 (defn- command
   "Build docker command"
@@ -39,33 +39,35 @@
         (into ppayload)
         (into pcommand))))

-(defn- parse-payload
+(defn- parse-body
+  "Parse docker engine response body"
   [response]
   (if (= (count response) 1)
-    nil
+    ""
     (parse-string (first response) true)))

 (defn- parse-http-code
+  "Parse docker engine response http code"
   [response]
-  (if (= (count response) 1)
-    (Integer. (first response))
-    (Integer. (second response))))
+  (Integer. (if (= (count response) 1)
+              (first response)
+              (second response))))

 (defn- execute
   "Execute docker command and parse result"
   [method uri headers payload]
   (let [cmd (command method uri headers payload)
-        result (apply shell/sh cmd)]
-    (if (= 0 (:exit result))
-      (let [response (string/split (:out result) #"\n")
-            payload (parse-payload response)
-            http-code (parse-http-code response)]
-        (if (> 400 http-code)
-          payload
+        cmd-result (apply shell/sh cmd)]
+    (if (= 0 (:exit cmd-result))
+      (let [response (string/split (:out cmd-result) #"\n")
+            response-body (parse-body response)
+            response-code (parse-http-code response)]
+        (if (> 400 response-code)
+          response-body
           (throw (ex-info "Docker engine error!"
-                          (assoc payload :code http-code)))))
+                          (assoc response-body :code response-code)))))
       (throw (ex-info "Docker client failure!"
-                      (parse-string (:err result) true))))))
+                      (parse-string (:err cmd-result) true))))))

 (defn get
   ([uri] (execute "GET" uri nil nil))


introduced env variable SWARMPIT_DOCKER_SOCK

#44

--- src/clj/swarmpit/docker/client.clj
+++ src/clj/swarmpit/docker/client.clj
@@ -6,8 +6,11 @@
             [cheshire.core :refer [parse-string generate-string]]
             [swarmpit.base64 :as base64]))

+(def ^:private socket
+  (or (System/getenv "SWARMPIT_DOCKER_SOCK")
+      "/var/run/docker.sock"))
 (def ^:private api-version "v1.28")
-(def ^:private base-cmd ["curl" "--unix-socket" "/var/run/docker.sock" "-w" "%{http_code}"])
+(def ^:private base-cmd ["curl" "--unix-socket" socket "-w" "%{http_code}"])

 (defn- map-headers
   "Map request `headers` map to curl vector cmd representation"


Simplify movement and fix bug in keypress event handler.

--- src/cljs/clj_typeshooter/main.cljs
+++ src/cljs/clj_typeshooter/main.cljs
@@ -51,14 +51,7 @@
    (while true
      (let [val (<! ch)
            sprite (:sprite @rocket)
-           old-speed (.getSpeed sprite)
-           ;; Increase ship speed if it's less than `max-speed'
-           speed (if (or (and (< val 0)
-                              (<= old-speed min-speed))
-                         (and (> val 0)
-                              (>= old-speed max-speed)))
-                   old-speed
-                   (+ old-speed val))
+           speed (if (= val 1) max-speed min-speed)
            updater #(merge % {:speed speed})]
        (.setSpeed sprite speed)
        (swap! rocket updater)))))
@@ -66,8 +59,9 @@
 ;; chan producers
 (defn handle-speed [ch update-ch event]
   (let [code (.-keyCode event)]
-    (go-handle! update-ch
-                (cond (= code 37) (>! ch -1) (= code 39) (>! ch 1) :else nil))))
+    (cond (= code 37) (go-handle! update-ch (>! ch -1))
+          (= code 39) (go-handle! update-ch (>! ch 1))
+          :else nil)))

 (defn handle-start-click [ch update-ch event]
   (go-handle! update-ch (>! ch {:state 1})))


Minor: fix incorrect brackets

Minor: fix incorrect brackets

--- src/cljs/mandelbrot_cljs/core.cljs
+++ src/cljs/mandelbrot_cljs/core.cljs
@@ -55,7 +55,7 @@
         startx  (aget (:mousedown-event @app-state) "pageX")
         starty  (aget (:mousedown-event @app-state) "pageY")
         finishx (aget e "pageX")
-        finishy {aget e "pageY"}]
+        finishy (aget e "pageY")]

     (if (or (< (modulus (- startx finishx)) 10)
             (< (modulus (- starty finishy)) 10)) ; Does this look like a click?


turn down the number of iterations

turn down the number of iterations

--- src/cljs/palimpsest/smoothing.cljs
+++ src/cljs/palimpsest/smoothing.cljs
@@ -168,7 +168,7 @@

 (def fit-error 16.0)
 (def adjust-error 4.0)
-(def max-adjust-iter 10)
+(def max-adjust-iter 4)

 (defn compute-max-error [coords bezier params]
   (->>


Modified index mapping for downloadable and browsable.

--- src/cmr/indexer/data/index_set.clj
+++ src/cmr/indexer/data/index_set.clj
@@ -40,7 +40,7 @@
   (assoc field-mapping :store "yes"))

 (defn not-indexed
-  "modifies a mapping to indicate that it should not be indexed"
+  "modifies a mapping to indicate that it should not be indexed and thus is not searchable."
   [field-mapping]
   (assoc field-mapping :index "no"))

@@ -217,8 +217,8 @@
                    :project-refs string-field-mapping
                    :project-refs.lowercase string-field-mapping
                    :revision-date         date-field-mapping
-                   :downloadable bool-field-mapping
-                   :browsable bool-field-mapping
+                   :downloadable (stored bool-field-mapping)
+                   :browsable (stored bool-field-mapping)
                    :attributes attributes-field-mapping
                    :downloadable-urls (not-indexed (stored string-field-mapping))
                    :browse-urls (not-indexed (stored string-field-mapping))


Replace bubbles' content to match the discuss flow

--- src/discuss/communication/lib.cljs
+++ src/discuss/communication/lib.cljs
@@ -50,8 +50,8 @@
                        (seq attacks) (vals attacks)
                        (seq attitudes) (vals attitudes)
                        :default [])
-        with-replaced-congratulation-bubble (breps/replace-congratulation-bubble bubbles)]
-    (lib/store-multiple-values-to-app-state! [['discussion/bubbles with-replaced-congratulation-bubble]
+        bubbles' (-> bubbles breps/replace-congratulation-bubbles breps/replace-profile-link-bubbles)]
+    (lib/store-multiple-values-to-app-state! [['discussion/bubbles bubbles']
                                               ['discussion/items update-items]
                                               ['discussion/add-step add-step]])))


folder:inTree

folder:inTree

--- src/grafter/rdf/ontologies/pmd.clj
+++ src/grafter/rdf/ontologies/pmd.clj
@@ -19,3 +19,4 @@
 (def folder:defaultTree  (folder "defaultTree"))
 (def folder:parentFolder (folder "parentFolder"))
 (def folder:resourceLocation (folder "resourceLocation"))
+(def folder:inTree       (folder "inTree"))


update

update

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -1,11 +1,11 @@
-{:user {:plugins [[lein-ancient "0.6.10"]
+{:user {:plugins [[lein-ancient "0.6.12"]
                   [lein-pprint "1.1.2"]
-                  [lein-codox "0.10.0"]
-                  [lein-kibit "0.1.2" :exclusions [org.clojure/clojure]]
-                  [jonase/eastwood "0.2.4"]]}
- :repl {:dependencies [^:displace [org.clojure/clojure "1.9.0-alpha17"]
-                       [ysmiraak "2017.09.11"]
-                       [com.cemerick/pomegranate "0.3.1"]]
+                  [lein-codox "0.10.3"]
+                  [lein-kibit "0.1.5" :exclusions [org.clojure/clojure]]
+                  [jonase/eastwood "0.2.5"]]}
+ :repl {:dependencies [^:displace [org.clojure/clojure "1.9.0-beta2"]
+                       [ysmiraak "2017.10.16"]
+                       [com.cemerick/pomegranate "0.4.0"]]
         :repl-options {:init-ns ysmiraak}
         :global-vars {*warn-on-reflection* true
                       *print-length* 11}


Programmes tidying.

Programmes tidying.

--- src/kixi/hecuba/api/programmes.clj
+++ src/kixi/hecuba/api/programmes.clj
@@ -1,13 +1,14 @@
 (ns kixi.hecuba.api.programmes
   (:require
+   [clojure.tools.logging :as log]
+   [liberator.core :refer (defresource)]
+   [liberator.representation :refer (ring-response)]
+   [qbits.hayt :as hayt]
    [cheshire.core :as json]
-   [clojure.tools.logging :as log]
+   [cemerick.friend :as friend]
    [kixi.hecuba.security :as sec]
    [kixi.hecuba.webutil :as util]
    [kixi.hecuba.webutil :refer (decode-body authorized? allowed? uuid stringify-values sha1-regex routes-from)]
-   [liberator.core :refer (defresource)]
-   [liberator.representation :refer (ring-response)]
-   [qbits.hayt :as hayt]
    [kixi.hecuba.storage.db :as db]
    [kixi.hecuba.storage.sha1 :as sha1]
    [kixi.hecuba.web-paths :as p]))
@@ -20,7 +21,6 @@
   (db/with-session [session (:hecuba-session store)]
     (let [request (:request ctx)
           items   (db/execute session (hayt/select :programmes))]
-      (log/infof "index-handle-ok ctx: %s" ctx)
       (map #(-> %
                 (dissoc :user_id)
                 (assoc :href (format programme-resource (:id %))
@@ -64,8 +64,8 @@
   :allowed-methods #{:get :post}
   :available-media-types ["application/json" "application/edn"]
   :known-content-type? #{"application/edn"}
-  :authorized? (authorized? store :programme)
-  :allowed? (allowed? store :programme)
+  :authorized? (authorized? store)
+  :allowed? (allowed? store)
   :handle-ok (partial index-handle-ok store)
   :post! (partial index-post! store)
   :handle-created (partial index-handle-created))
@@ -74,7 +74,7 @@
   :allowed-methods #{:get}
   :available-media-types ["application/json" "application/edn"]
   :known-content-type? #{"application/edn"}
-  :authorized? (authorized? store :programme)
-  :allowed? (allowed? store :programme)
+  :authorized? (authorized? store)
+  :allowed? (allowed? store)
   :exists? (partial resource-exists? store)
   :handle-ok (partial resource-handle-ok))


Refactored core_local to make future middleware easier to write.

--- src/appengine_magic/core_local.clj
+++ src/appengine_magic/core_local.clj
@@ -9,15 +9,25 @@
 (import java.io.File)

+(defn default-war-root []
+  (-> (clojure.lang.RT/baseLoader)
+      (.getResource ".")
+      .getFile
+      java.net.URLDecoder/decode
+      (File. "../resources")
+      .getAbsolutePath))
+
+
 (defn open-resource-stream [resource-name]
   (-> (ClassLoader/getSystemClassLoader) (.getResourceAsStream resource-name)))

-(defn wrap-war-static [app #^String war-root]
-  (fn [req] (let [#^String uri (:uri req)]
-              (if (.startsWith uri "/WEB-INF")
-                  (app req)
-                  ((wrap-file app war-root) req)))))
+(defn wrap-war-static [app, #^String war-root]
+  (fn [req]
+    (let [#^String uri (:uri req)]
+      (if (.startsWith uri "/WEB-INF")
+          (app req)
+          ((wrap-file app war-root) req)))))

 (defmacro def-appengine-app [app-var-name handler & {:keys [war-root]}]
@@ -25,16 +35,11 @@
         (let [handler# ~handler
               war-root-arg# ~war-root
               war-root# (if (nil? war-root-arg#)
-                            (-> (clojure.lang.RT/baseLoader)
-                                (.getResource ".")
-                                .getFile
-                                java.net.URLDecoder/decode
-                                (File. "../resources")
-                                .getAbsolutePath)
+                            (default-war-root)
                             war-root-arg#)]
-          {:handler (wrap-war-static
-                     (environment-decorator handler#)
-                     war-root#)
+          {:handler (-> handler#
+                        environment-decorator
+                        (wrap-war-static war-root#))
            :war-root war-root#})))


fixed lein-bin clasloader configuration

fixed lein-bin clasloader configuration

--- qanal/project.clj
+++ qanal/project.clj
@@ -22,5 +22,5 @@
                              [lein-bin "0.3.5"]]}}

   :jvm-opts ["-server" "-Dfile.encoding=utf-8"]
-  :bin {:name "qanal" :bootclasspath "false"}
+  :bin {:name "qanal" :bootclasspath false}
   )


Add projects section to sidebar

Add projects section to sidebar

--- app/src/cljs/app/app.cljs
+++ app/src/cljs/app/app.cljs
@@ -1,6 +1,8 @@
 (ns app.app
   (:require [cljsjs.material]
-            [reagent.core :as reagent]))
+            [reagent.core :as reagent]
+            [app.components :as comps]
+            [app.res :refer [resume]]))

 (defn fixed-header-and-drawer-component [content]
   [:div.mdl-layout.mdl-js-layout.mdl-layout--fixed-drawer.mdl-layout--fixed-header
@@ -10,19 +12,28 @@
    [:div.mdl-layout__drawer
     [:span.mdl-layout-title "Resume"]
     [:nav.mdl-navigation
-     [:a.mdl-navigation__link {:href "#"} "About"]]]
+     [:a.mdl-navigation__link {:href "#contact"} "Contact"]
+     [:a.mdl-navigation__link {:href "#about"} "About"]
+     [:a.mdl-navigation__link {:href "#projects"} "Projects"]]]
    [:main.mdl-layout__content
     [:div.page-content
      content]]])

-(defn some-component []
+(defn main-component []
   [:div
    [fixed-header-and-drawer-component
-    [:h3 "This is your app"]]])
-
+    [:div
+     [comps/contact-component (:name (:contact resume))
+      (:email (:contact resume))
+      (:phone (:contact resume))]
+     [comps/about-component
+      [:p (:profile resume)]]
+     [comps/projects-component
+      (:projects resume)]]]])
+

 (defn init []
-  (reagent/render-component [some-component]
+  (reagent/render-component [main-component]
                             (.getElementById js/document "container")))


Add validation to some example3 funcs

Add validation to some example3 funcs

--- src/chartreuse_vortex/example3.cljs
+++ src/chartreuse_vortex/example3.cljs
@@ -42,6 +42,10 @@
                          :sprites []}))

 (defn linear-hits [x dx targetx maxtime]
+  {:pre [(number? x)
+         (number? dx)
+         (number? targetx)
+         (number? maxtime)]}
   (if (common/float= 0 dx)
     maxtime
     (let [distance (- targetx x)
@@ -51,6 +55,8 @@
         (min time maxtime)))))

 (defn ballistic-fall [x y dx dy g elapsedtime]
+  {:pre [(number? x)
+         (number? y)]}
   "Given a start position, velocity, gravity, and time computes
 the new position and velocity after a given time"
   (let [newx (+ x (* dx elapsedtime))


Stops-view transacts to entities map

Stops-view transacts to entities map

--- src/cljs/gtfve/controllers/api.cljs
+++ src/cljs/gtfve/controllers/api.cljs
@@ -2,7 +2,8 @@
   (:require-macros [cljs.core.async.macros :refer [go go-loop]]
                    [gtfve.macros :refer [<?]])
   (:require [om.core :as om]
-            [cljs.core.async :as async :refer [put! <! close!]]))
+            [cljs.core.async :as async :refer [put! <! close!]]
+            [gtfve.utils :as utils]))

 (defmulti api-event
   (fn [event status args state cursors] [event status]))
@@ -25,4 +26,5 @@
         results (:response result)
         key-val-xf (map (fn [stop] [(:db/id stop) stop]))
         results-map (transduce key-val-xf conj {} results)]
-    (om/update! (data) :stops results-map)))
+    (om/transact! (data) :entities #(utils/deep-merge % results-map))
+    (om/update! (data) :stops (keys results-map))))


more make sense default value

more make sense default value

--- src/me/shenfeng/http/server.clj
+++ src/me/shenfeng/http/server.clj
@@ -13,10 +13,10 @@
 (defn run-server [handler {:keys [port thread ip max-body max-line worker-name-prefix]
                            :or {ip "0.0.0.0"
                                 port 8090
-                                thread 2
+                                thread 4
                                 worker-name-prefix "worker-"
-                                max-body 20480
-                                max-line 2048}}]
+                                max-body 8388608 ; max http body: 8m
+                                max-line 4096}}] ; max http inital line length: 4K
   (let [h (RingHandler. thread handler worker-name-prefix)
         s (HttpServer. ip port h max-body max-line)]
     (.start s)


Add docstring to connect-plugin

Add docstring to connect-plugin

--- src/com/wsscode/pathom/connect.cljc
+++ src/com/wsscode/pathom/connect.cljc
@@ -1331,6 +1331,23 @@
 ;; plugins

 (defn connect-plugin
+  "This plugin facilitates the connect setup in a parser. It works by wrapping the parser,
+  it setups the connect resolver and mutation dispatch using the embedded dispatchers (check resolver
+  map format in the book for more details). It also sets up the resolver weights for load
+  balacing calculation. Here are the available options to configure the plugin:
+
+  `::pc/indexes` - provide an index atom to be used, otherwise the plugin will create one
+  `::pc/register` - a resolver, mutation or sequence of resolvers/mutations to register in
+  the index
+
+  This plugin also looks for the key `::pc/register` in the other plugins used in the
+  parser configuration, this enable plugins to provide resolvers/mutations to be available
+  in your connect system.
+
+  By default this plugin will also register resolvers to provide the index itself, if
+  you for some reason need to hide it you can dissoc the `::pc/register` from the output
+  and they will not be available, but consider that doing so you lose the ability to
+  have instrospection in tools like Pathom Viz and Fulcro Inspect."
   ([] (connect-plugin {}))
   ([{::keys [indexes] :as env}]
    (let [indexes (or indexes (atom {}))]


Cosmetic

Cosmetic

--- src/overtime/instr_control.clj
+++ src/overtime/instr_control.clj
@@ -16,22 +16,6 @@
 (defmethod synth-instance :instr [_type key] (instr key))
 (defmethod synth-instance :trigger [_type key] (micro/trigger key))
 (defmethod synth-instance :pan [_type key] (micro/pan key))
-
-(defn play-instr
-  [instr-key synth params]
-  (log/info "Playing instr" instr-key)
-  (swap! instrs assoc instr-key (-> (u/check-nil synth "Synth" instr-key)
-                                    (apply params))))
-
-(defn play-sound
-  [instr-key sound-def-key]
-  (let [{:keys [synth params]} (snd/sound-def sound-def-key)]
-    (play-instr instr-key synth params)))
-
-(defmulti play-sound-at (fn [_time instr-type & _args] instr-type))
-(defmethod play-sound-at :instr
-  [time _instr-type & [instr-key sound-def-key]]
-  (u/apply-by time (ot/at time (play-sound instr-key (or sound-def-key instr-key)))))

 (defmulti set-params (fn [type _key & _params] type))
 (defmethod set-params :default
@@ -69,6 +53,22 @@
 (defn set-param-over-time-at [time & params] (u/apply-by time (apply set-param-over-time params)))

+(defn play-instr
+  [instr-key synth params]
+  (log/info "Playing instr" instr-key)
+  (swap! instrs assoc instr-key (-> (u/check-nil synth "Synth" instr-key)
+                                    (apply params))))
+
+(defn play-sound
+  [instr-key sound-def-key]
+  (let [{:keys [synth params]} (snd/sound-def sound-def-key)]
+    (play-instr instr-key synth params)))
+
+(defmulti play-sound-at (fn [_time instr-type & _args] instr-type))
+(defmethod play-sound-at :instr
+  [time _instr-type & [instr-key sound-def-key]]
+  (u/apply-by time (ot/at time (play-sound instr-key (or sound-def-key instr-key)))))
+
 (defn stop-instr
   ([instr-key] (stop-instr instr-key 10))
   ([instr-key num-incrs]


ionian's now a function.

ionian's now a function.

--- src/overtunes/songs/at_all.clj
+++ src/overtunes/songs/at_all.clj
@@ -18,12 +18,12 @@
 (def note# (comp sampled-piano ground))
 (defn chord# [chord] (doseq [note (vals chord)] (note# note)))

-(def ionian (cycle [0 2 4 5 7 9 11]))
+(def ionian #([0 2 4 5 7 9 11] (mod % 7)))
 (defn triad [scale root]
   (zipmap [:i :iii :v]
-          [(nth scale root)
-           (nth scale (+ root 2))
-           (nth scale (+ root 4))]))
+          [(scale root)
+           (scale (+ root 2))
+           (scale (+ root 4))]))

 (defn lower [note] (- note 12))
 (defn with-base [chord]
@@ -54,12 +54,12 @@
       (even-melody# (from timing 1) notes))))

 (defn play []
-  (let [timing (from (bpm 120) 2)]
+  (let [timing (from (bpm 240) 2)]
     (even-melody# timing (take 32 (cycle [9 7])))
     (rythm-n-bass# timing (take 16 (cycle progression)))
-    (even-melody# (speed-up (from timing 31) 2) [4 7 9 7 7 4 7])
-    (even-melody# (speed-up (from timing 39) 2) [7 2 4 2 2 7 2])
-    (even-melody# (speed-up (from timing 47) 2) [7 2 4 2 2 7 2 4 5 7])
-    (even-melody# (speed-up (from timing 55) 2) [7 2 4 2 2 7 2 4 2 11])))
+    (even-melody# (speed-up (from timing 31) 2) (map ionian [2 4 5 4 4 2 4]))
+    (even-melody# (speed-up (from timing 39) 2) (map ionian [5 1 2 1 1 5 1]))
+    (even-melody# (speed-up (from timing 47) 2) (map ionian [5 1 2 1 1 5 1 2 3 4]))
+    (even-melody# (speed-up (from timing 55) 2) (map ionian [5 1 2 1 1 5 1 2 1 6]))))

 (play)


Separate munging layer.

Separate munging layer.

--- src/onyx/peer/task_pipeline.clj
+++ src/onyx/peer/task_pipeline.clj
@@ -10,11 +10,15 @@
 (defn create-tx-session [{:keys [queue]}]
   (extensions/create-tx-session queue))

-(defn establish-new-payload [{:keys [sync peer-node payload-ch]}]
+(defn new-payload [sync peer-node payload-ch]
   (let [peer-contents (extensions/read-place sync peer-node)
         node (extensions/create sync :payload)]
-    (extensions/write-place sync (assoc :payload node))
-    (extensions/on-change sync node #(>!! payload-ch %))))
+    (extensions/write-place sync (assoc :payload node))))
+
+(defn munge-new-payload [{:keys [sync peer-node payload-ch] :as event}]
+  (let [node (new-payload sync peer-node payload-ch)]
+    (extensions/on-change sync node #(>!! payload-ch %))
+    (assoc event :new-payload-node node)))

 (defn munge-open-session [event session]
   (assoc event :session session))
@@ -106,7 +110,7 @@

 (defn reset-payload-node [reset-ch payload-ch]
   (when-let [event (<!! reset-ch)]
-    (establish-new-payload event)))
+    (munge-new-payload event)))

 (defrecord TaskPipeline [payload sync queue payload-ch]
   component/Lifecycle


Default setup/teardown.

Default setup/teardown.

[ci skip]

--- src/onyx/windowing/triggers.clj
+++ src/onyx/windowing/triggers.clj
@@ -68,3 +68,11 @@
 (defmethod refine-state :discarding
   [event trigger]
   (get-and-set! (:onyx.core/window-state event) nil))
+
+(defmethod trigger-setup :default
+  [event _ _]
+  event)
+
+(defmethod trigger-teardown :default
+  [event _ _]
+  event)


Remove useless comment

Remove useless comment

--- src/clj/com/beardandcode/forms.clj
+++ src/clj/com/beardandcode/forms.clj
@@ -13,5 +13,4 @@
            hiccup [:form {:action action :method method}
                    (render/schema schema-map)
                    [:input {:type "submit" :value (schema-map "submit")}]]]
-       ;;(println hiccup)
        hiccup)))


Add color overlay while the canvas is re-drawing

--- src/cljs/mandelbrot_cljs/core.cljs
+++ src/cljs/mandelbrot_cljs/core.cljs
@@ -33,6 +33,30 @@

   (aset overlay-canvas "width"(.-innerWidth js/window))
   (aset overlay-canvas "height"(.-innerHeight js/window)))
+
+(defn clear-overlay!
+  "Clears the whole overlay canvas"
+  []
+  (.clearRect overlay-context 0 0
+              (aget overlay-canvas "width")
+              (aget overlay-canvas "height")))
+
+(defn add-overlay-rectangle!
+  "Adds a rectangle to the overlay canvas (and optionally clears all other rectangles)"
+  [x0 y0 x1 y1 & {:keys [clear? color opacity type] :or {clear? true color "green" opacity 1 type :stroke}}]
+  (aset overlay-context "globalAlpha" opacity)
+  (aset overlay-context "lineWidth" 1)
+
+
+  (when clear? (clear-overlay!))
+
+  (case type
+
+    :stroke (do (aset overlay-context "strokeStyle" color)
+                (.strokeRect overlay-context x0 y0 (- x1 x0) (- y1 y0)))
+
+    :fill (do (aset overlay-context "fillStyle" color)
+              (.fillRect overlay-context x0 y0 (- x1 x0) (- y1 y0)))))

 (defn render-mandelbrot!
   "Iterate over every pixel in the canvas, rendering the mandelbrot
@@ -74,20 +98,9 @@

     (.putImageData context idata 0 0)

+    (clear-overlay!)
+
     (.log js/console "Done in: " (int (* 1000 (/ (* height width)  (- (.getTime (js/Date.)) start)))) "px/s")))
-
-(defn add-overlay-rectangle!
-  "Adds a rectangle to the overlay canvas (and optionally clears all other rectangles)"
-  [x0 y0 x1 y1 & {:keys [clear? color] :or {clear? true color "green"}}]
-  (aset overlay-context "lineWidth" 1)
-  (aset overlay-context "strokeStyle" color)
-
-  (when clear?
-    (.clearRect overlay-context 0 0
-                (aget overlay-canvas "width")
-                (aget overlay-canvas "height")))
-
-  (.strokeRect overlay-context x0 y0 (- x1 x0) (- y1 y0)))

 (set! (.-onmousedown overlay-canvas) (fn [e]
                                        (swap! app-state assoc :mousedown-event e)))
@@ -167,7 +180,13 @@
            (fn [_ _ old-state new-state]
              (when-not (= (:rendering-data old-state)
                           (:rendering-data new-state))
-               (render-mandelbrot! new-state))))
+
+               (add-overlay-rectangle!
+                0 0
+                (aget overlay-canvas "width") (aget overlay-canvas "height")
+                :opacity 0.2 :color "green" :clear? true :type :fill)
+
+               (.setTimeout js/window #(render-mandelbrot! new-state) 10))))

 (render-mandelbrot! @app-state)


Note for future self

Note for future self

--- src/cljs/openslack/views/text.cljs
+++ src/cljs/openslack/views/text.cljs
@@ -98,6 +98,7 @@
   (let [contact-local (str/ltrim contact-name "@")]
     ;; TODO: if it's the logged-in users name we may want to do something special
     (if-let [maybe-contact (st/get-contact @st/state contact-local)]
+      ;; TODO: mention-user class sets background, doesn't look good with links
       [:a {:href (contact-route {:name contact-local})} contact-name]
       [:span contact-name])))


Show availability in human-readable form when there isn't a status string

--- src/cljs/openslack/views/user.cljs
+++ src/cljs/openslack/views/user.cljs
@@ -2,6 +2,12 @@
   (:require [om.core :as om :include-macros true]
             [sablono.core :as s :include-macros true]
             [openslack.state :as st]))
+
+(def availability->default-status
+  {:available "Online"
+   :unavailable "Offline"
+   :dnd "Busy"
+   :xa "Busy"})

 (defn user [state owner]
   (reify
@@ -15,7 +21,7 @@
               presence (st/get-presence @st/state {:jid jid})]
           (s/html
            [:div.active-user
-                                        ; TODO: avatar
+            ;; TODO: avatar
             [:img
              {:height "50",
               :width "50",
@@ -23,8 +29,11 @@
               :src "/static/imgs/placerholder-avatar-1.jpg"}]
             [:div.square
              [:div.row [:h2 (:local jid)]]
-             (let [status-text [:p.status-text (:status presence)]]
-               (condp = (:availability presence :available)
+             (let [availability (:availability presence :available)
+                   default-status (availability->default-status availability)
+                   status (:status presence)
+                   status-text [:p.status-text (if status status default-status)]]
+               (condp = availability
                  :available [:div.row [:div.status.online] status-text]
                  :unavailable [:div.row [:div.status.offline] status-text]
                  :dnd [:div.row [:div.status.busy] status-text]))]]))))))


private

private

--- src/cljs/tictactoe/logic/turn.cljs
+++ src/cljs/tictactoe/logic/turn.cljs
@@ -32,7 +32,7 @@
     (board/full-board? (:board turn))
     (has-winner? (:board turn))))

-(defn valid-move?
+(defn- valid-move?
   [turn x y]
   (and
     (board/empty-cell? (:board turn) x y)


refactoring

refactoring

--- src/cljs/triboard/logic/board.cljs
+++ src/cljs/triboard/logic/board.cljs
@@ -1,8 +1,7 @@
 (ns triboard.logic.board
   (:require
     [cljs.spec :as s :include-macros true]
-    [triboard.logic.constants :as cst]
-    ))
+    [triboard.logic.constants :as cst]))

 ;; -----------------------------------------
@@ -59,15 +58,16 @@
   "Creates a new board with initial positions of each players"
   []
   (reduce
-    (fn [r [color point]] (assoc-in r point color))
-    empty-board (init-positions)))
+    (fn [board [color point]] (assoc-in board point color))
+    empty-board
+    (init-positions)))

 (def get-cell-at get-in)

 (defn to-iterable
   "Access to the board as a list of coordinates with corresponding owner"
   [board]
-  (for [[x y :as coord] cst/all-positions]
+  (for [coord cst/all-positions]
     [coord (get-cell-at board coord)]))

 (defn empty-cells


Renaming vars for clarity

Renaming vars for clarity

--- src/midje/internal_ideas/fakes.clj
+++ src/midje/internal_ideas/fakes.clj
@@ -115,24 +115,24 @@
  ;;; Binding

-(defmulti matches-call? (fn [fake faked-function args]
+(defmulti matches-call? (fn [fake function-var actual-args]
                           (:type fake)))

 (defmethod matches-call? :not-called
-  [fake faked-function args]
-  (= faked-function (fake :lhs)))
+  [fake function-var actual-args]
+  (= function-var (fake :lhs)))

 (defmethod matches-call? :default
-  [fake faked-function args]
-  (and (= faked-function (fake :lhs))
-       (= (count args) (count (fake :arg-matchers)))
-       (extended-list-= args (fake :arg-matchers))))
-
-(defn find-matching-call [faked-function args fakes]
-  (first (filter #(matches-call? % faked-function args) fakes)))
-
-(defn best-call-action [faked-var args fakes]
-  (let [found (find-matching-call faked-var args fakes)]
+  [fake function-var actual-args]
+  (and (= function-var (fake :lhs))
+       (= (count actual-args) (count (fake :arg-matchers)))
+       (extended-list-= actual-args (fake :arg-matchers))))
+
+(defn find-matching-call [function-var actual-args fakes]
+  (first (filter #(matches-call? % function-var actual-args) fakes)))
+
+(defn best-call-action [function-var actual-args fakes]
+  (let [found (find-matching-call function-var actual-args fakes)]
     (cond found
           {:use-fake true :matching-fake found}

@@ -140,14 +140,14 @@
           {:fail true})))

-(defn call-faker [faked-function args fakes]
+(defn call-faker [function-var actual-args fakes]
   "This is the function that handles all mocked calls."
-  (let [found (find-matching-call faked-function args fakes)]
+  (let [found (find-matching-call function-var actual-args fakes)]
     (if-not found
       (do
         (clojure.test/report {:type :mock-argument-match-failure
-                 :lhs faked-function
-                 :actual args
+                 :lhs function-var
+                 :actual actual-args
                  :position (:position (first fakes))}))
       (do
         (swap! (found :count-atom) inc)


"Unlazify" parallel fetcher

"Unlazify" parallel fetcher

--- src/org/spootnik/cyanite/store.clj
+++ src/org/spootnik/cyanite/store.clj
@@ -157,7 +157,9 @@
       (.add b (.bind s (into-array Object v))))
     b))

-(defn par-fetch [session fetch! paths tenant rollup period from to]
+(defn par-fetch
+  "Fetch data in parallel fashion."
+  [session fetch! paths tenant rollup period from to]
   (let [futures
         (doall (map #(future
                        (debug "fetching path from store: " % tenant
@@ -169,6 +171,7 @@
                                        from to]
                               :fetch-size Integer/MAX_VALUE})
                             (map detect-aggregate)
+                            (doall)
                             (seq)))
                     paths))]
     (seq (into [] (r/remove nil? (r/reduce into [] (map deref futures)))))))


remove condition (was always false)

remove condition (was always false)

--- src/status_im/android/core.cljs
+++ src/status_im/android/core.cljs
@@ -27,9 +27,6 @@

                            (and @webview (:can-go-back? @result-box))
                            (do (.goBack @webview) true)
-
-                           (#{:home :wallet :my-profile} view-id)
-                           (do (.exitApp react/back-handler))

                            (< 1 (count @stack))
                            (do (dispatch [:navigate-back]) true)


:bug: Properly raise not found exception on get-by-id helper.

--- backend/src/app/db.clj
+++ backend/src/app/db.clj
@@ -131,7 +131,7 @@
                 (:for-update opts)
                 (assoc :suffix "for update"))
          res  (exec-one! ds (jdbc-bld/for-query table params opts) opts)]
-     (when (:deleted-at res)
+     (when (or (:deleted-at res) (not res))
        (ex/raise :type :not-found))
      res)))


:fire: Remove unused code.

:fire: Remove unused code.

--- backend/tests/user.clj
+++ backend/tests/user.clj
@@ -17,15 +17,12 @@
    [clojure.java.io :as io]
    [clojure.repl :refer :all]
    [criterium.core :refer [quick-bench bench with-progress-reporting]]
-   [expound.alpha :as expound]
    [promesa.core :as p]
-   ;; [sieppari.core :as sp]
-   ;; [sieppari.context :as spx]
-   ;; [buddy.core.codecs :as codecs]
-   ;; [buddy.core.codecs.base64 :as b64]
-   ;; [buddy.core.nonce :as nonce]
+   [promesa.exec :as pe]
    [mount.core :as mount]
    [uxbox.main]))
+
+;; --- Benchmarking Tools

 (defmacro run-quick-bench
   [& exprs]
@@ -43,20 +40,7 @@
   [& exprs]
   `(bench (do ~@exprs)))

-(def stress-data
-  {:shapes [{:id #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :name "Canvas-1", :type :canvas, :page #uuid "1b7d4218-e3be-5254-9582-18f767d30501", :x1 200, :y1 200, :x2 1224, :y2 968} {:stroke-color "#000000", :name "Rect-1-copy-4-copy-1", :y1 334, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "c1966bac-b568-4f8f-9917-227cc37e5672", :x1 674, :proportion 1.353448275862069, :y2 450, :x2 831, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-7-copy-1", :y1 400, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "20f11fd1-e9a2-41b1-a539-1298194c6d07", :x1 836, :proportion 1.353448275862069, :y2 516, :x2 993, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-11", :y1 355, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "e1efb49a-03dd-4b87-b568-f35e3a85cf19", :x1 223, :proportion 1.353448275862069, :y2 471, :x2 380, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-10", :y1 404, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "4bf2440d-38d4-461b-af41-001cfb00be49", :x1 928, :proportion 1.353448275862069, :y2 520, :x2 1085, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-9", :y1 525, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "bd1cb612-3960-4428-b030-ea0e59c70b06", :x1 497, :proportion 1.353448275862069, :y2 641, :x2 654, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-8", :y1 393, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "78104154-3d6b-43dc-8444-873ca3285bca", :x1 395, :proportion 1.353448275862069, :y2 509, :x2 552, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-7", :y1 711, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "35540bc3-e1a9-4052-8cb7-a4b07da229dd", :x1 838, :proportion 1.353448275862069, :y2 827, :x2 995, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-6", :y1 502, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "a4d2ef30-1da9-4aba-98ed-15088aba36e0", :x1 893, :proportion 1.353448275862069, :y2 618, :x2 1050, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-5", :y1 479, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "4de4a87a-74f3-47ce-85e6-a0d5da9adb62", :x1 595, :proportion 1.353448275862069, :y2 595, :x2 752, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-4", :y1 645, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "c6c062d2-20fe-4e48-8035-63358db2df4c", :x1 676, :proportion 1.353448275862069, :y2 761, :x2 833, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-3", :y1 609, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "b3089c39-24f9-4574-8df1-d1e4596a6200", :x1 831, :proportion 1.353448275862069, :y2 725, :x2 988, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-2", :y1 404, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "da7c624b-807a-41b1-84a6-7e14ed4f150c", :x1 733, :proportion 1.353448275862069, :y2 520, :x2 890, :height 2} {:stroke-color "#000000", :name "Rect-1-copy-1", :y1 609, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "ec65a0a8-9de1-48d7-b245-71f98961dc7c", :x1 518, :proportion 1.353448275862069, :y2 725, :x2 675, :height 2} {:stroke-color "#000000", :name "Rect-1", :y1 566, :width 2, :type :rect, :page #uuid "2ef8e638-4018-5581-aa18-0887f126966c", :canvas #uuid "352cbd3c-1336-5793-80f7-31027d0acfe7", :proportion-lock false, :id #uuid "c7eafc25-214a-4d16-abbe-19aa0f2eb25b", :x1 306, :proportion 1.353448275862069, :y2 682, :x2 463, :height 2}]})
-
-;; (def a1 (blob/encode stress-data))
-;; (def b1 (blob/encode-with-json stress-data))
-;; (def b2 (blob/encode-json-snappy stress-data))
-
 ;; --- Development Stuff
-
-;; (defn- make-secret
-;;   []
-;;   (-> (nonce/random-bytes 64)
-;;       (b64/encode true)
-;;       (codecs/bytes->str)))

 (defn- start
   []
@@ -72,15 +56,8 @@
   (stop)
   (repl/refresh :after 'user/start))

-;; (defn- start-minimal
-;;   []
-;;   (-> (mount/only #{#'uxbox.config/config
-;;                     #'uxbox.db/datasource
-;;                     #'uxbox.migrations/migrations})
-;;       (mount/start)))
-
-(defn- run-test
-  ([] (run-test #"^uxbox.tests.*"))
+(defn- run-tests
+  ([] (run-tests #"^uxbox.tests.*"))
   ([o]
    ;; (repl/refresh)
    (cond


define spec find-support-node

define spec find-support-node

--- src/synthesis_crawlers/core.clj
+++ src/synthesis_crawlers/core.clj
@@ -176,9 +176,7 @@
   (conj (into [] (.parents elem)) elem))

 (s/fdef find-reachable-attrs
-        :args (s/cat :attr-nodes (s/map-of string?
-                                           (s/map-of keyword?
-                                                     (s/coll-of #(instance? Element %))))))
+        :args (s/cat :attr-nodes ::attributed-nodes-in-pages))
 (defn find-reachable-attrs
   [attr-nodes]
   (let [result (for [[url attr-nodes] attr-nodes
@@ -192,11 +190,8 @@
             {}
             result)))

-(s/fdef find-reachable-attrs
-        :args (s/cat :attr-nodes (s/map-of string?
-                                           (s/map-of keyword?
-                                                     (s/coll-of #(instance? Element %))))))
-
+(s/fdef find-support-nodes
+        :args (s/cat :attr-nodes ::attributed-nodes-in-pages))
 (defn find-support-nodes
   [url-attr-nodes]
   (let [result (for [[url attr-nodes] url-attr-nodes


test hook

test hook

--- src/main/cawala/ui/components.cljs
+++ src/main/cawala/ui/components.cljs
@@ -11,7 +11,7 @@
                     {:db/id id :person/name name :person/age age})}
   (dom/li
    (dom/h5 (str name "(age: " age ")")
-           (dom/button {:onClick #(onDelete id)} "A")
+           (dom/button {:onClick #(onDelete id)} "B")
            (dom/button {:onClick #(df/refresh! this)} "Refresh"))))

 (def ui-person (prim/factory Person {:keyfn :person/name}))


split up benchmarking for triangle generation, paint, and total

--- src/sierpinski_sieve/core.cljs
+++ src/sierpinski_sieve/core.cljs
@@ -44,8 +44,9 @@
 (defn main [size]
   (reagent/render [(render-canvas size)]
                   (. js/document (getElementById "app")))
-  (time (blit/paint "canvas" size (take size (sieve '(1) 2))))
-  (time (paint "canvas" size (take size (sieve '(1) 2)))))
+  (time
+   (let [triangle (time (doall (take size (sieve '(1) 2))))]
+     (time (paint "canvas" size triangle)))))

 (main 325)


Add bootstrap css and js

Add bootstrap css and js

--- src/sweng_hw6_grader/views.clj
+++ src/sweng_hw6_grader/views.clj
@@ -6,10 +6,15 @@
   (hiccup/html5
     [:head
      [:meta {:charset "utf-8"}]
+     [:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
+     (hiccup/include-css "//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css")
      [:title title]]
     [:body
+     [:div.container
       [:h1 "SwEng 2013 Homework 6 Contest"]
-      body]))
+      body
+      (hiccup/include-js "https://code.jquery.com/jquery.js")
+      (hiccup/include-js "//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js")]]))

 (def issue-titles {:violations "Issues"


Add missing divide function to point reladed utils.

--- src/uxbox/util/geom/point.cljs
+++ src/uxbox/util/geom/point.cljs
@@ -86,6 +86,13 @@
     (Point. (* (:x p) (:x other))
             (* (:y p) (:y other)))))

+(defn divide
+  [p other]
+  {:pre [(point? p)]}
+  (let [other (-point other)]
+    (Point. (/ (:x p) (:x other))
+            (/ (:y p) (:y other)))))
+
 (defn distance
   "Calculate the distance between two points."
   [p other]


Accomodate Karma log formats, and prefix ERROR to all error messages

--- library/src/doo/runner.cljs
+++ library/src/doo/runner.cljs
@@ -57,12 +57,15 @@
     (try
       (*main-cli-fn* a)
       (catch :default e
-        (println "\nERROR: Exception outside tests:")
-        (println e)
+        (println)
+        (println "ERROR: Exception outside tests:")
+        (println "ERROR:" e)
         (if (.hasOwnProperty e "stack")
-          (do (println "\nERROR: Stacktrace:")
-              (println (.-stack e)))
-          (println "\nNo stacktrace available."))
+          (do (println)
+              (println "ERROR: Stacktrace:")
+              (println "ERROR:" (.-stack e)))
+          (do (println)
+              (println "ERROR: No stacktrace available.")))
         (exit! false)))))

 (defn set-entry-point!


Fix filter follow-ups by assignee to avoid duplicates.

--- src/oc/storage/resources/entry.clj
+++ src/oc/storage/resources/entry.clj
@@ -454,7 +454,7 @@
    {:pre [(db-common/conn? conn)]}
    (let [old-follow-ups (:follow-ups original-entry)
          all-follow-up-assignee (map #(-> % :assignee :user-id) follow-ups)
-         filtered-follow-ups (filterv #(not (#{(-> % :assignee :user-id)} (set all-follow-up-assignee))) old-follow-ups)
+         filtered-follow-ups (filterv #(not ((set all-follow-up-assignee) (-> % :assignee :user-id))) old-follow-ups)
          new-follow-ups (vec (concat filtered-follow-ups follow-ups))
          final-entry (assoc original-entry :follow-ups new-follow-ups)]
     (update-entry-no-version! conn (:uuid original-entry) final-entry user))))
@@ -468,7 +468,7 @@
         other-follow-ups (filterv #(not= (:uuid %) (:uuid follow-up)) (:follow-ups original-entry))
         final-follow-ups (vec (conj other-follow-ups completed-follow-up))
         updated-entry (assoc original-entry :follow-ups final-follow-ups)]
-    (update-entry-no-version! conn entry-uuid updated-entry user)))
+    (update-entry-no-version! conn (:uuid original-entry) updated-entry user)))

 ;; ----- Data about entries -----


Move parallel fetcher to the function

Move parallel fetcher to the function

--- src/org/spootnik/cyanite/store.clj
+++ src/org/spootnik/cyanite/store.clj
@@ -155,6 +155,23 @@
     (doseq [v values]
       (.add b (.bind s (into-array Object v))))
     b))
+
+(defn par-fetch [session fetch! paths tenant rollup period from to]
+  (let [futures
+        (doall (map #(future
+                       (let [path %]
+                         (debug "fetching path from store: " path
+                                tenant rollup period from to)
+                         (->> (alia/execute
+                               session fetch!
+                               {:values [[path] tenant (int rollup)
+                                         (int period)
+                                         from to]
+                                :fetch-size Integer/MAX_VALUE})
+                              (map detect-aggregate)
+                              (seq))))
+                    paths))]
+    (remove nil? (reduce concat (map deref futures)))))

 (defn cassandra-metric-store
   "Connect to cassandra and start a path fetching thread.
@@ -202,20 +219,9 @@
          {:values [ttl data tenant rollup period path time]}))
       (fetch [this agg paths tenant rollup period from to]
         (debug "fetching paths from store: " paths tenant rollup period from to)
-        (if-let [data
-                 (and (seq paths)
-                      (let [futures
-                            (doall (map #(future
-                                           (->> (alia/execute
-                                                 session fetch!
-                                                 {:values [[%] tenant (int rollup)
-                                                           (int period)
-                                                           from to]
-                                                  :fetch-size Integer/MAX_VALUE})
-                                                (map detect-aggregate)
-                                                (seq)))
-                                           paths))]
-                        (remove nil? (reduce concat (map deref futures)))))]
+        (if-let [data (and (seq paths)
+                           (par-fetch session fetch! paths tenant rollup
+                                      period from to))]
           (let [min-point  (:time (first data))
                 max-point  (-> to (quot rollup) (* rollup))
                 nil-points (->> (range min-point (inc max-point) rollup)


Added save button to webpage

Added save button to webpage

--- src/wishlistd/views/common.clj
+++ src/wishlistd/views/common.clj
@@ -42,6 +42,7 @@
                 [:div.content
                  [:div.page-header
                   [:h1 "Wishlistd"]
+                  [:input {:id "save-wishlist" :class "btn primary" :type "submit" :value "Save" :style "margin-left:550px;margin-right:-100px"}]
                   [:input {:id "create-wishlist" :class "btn primary" :type "submit" :value "Create wishlist" :style "margin-left:550px;margin-right:-100px"}]]
                 [:div.row
                  [:div.span10


[FIX #3629] remove extra hyphenation of text in empty home tab

Signed-off-by: Julien Eluard <c768e13f1ba4c3ebed2909a1fc1e4b50bb021a2f@gmail.com>

--- src/status_im/translations/en.cljs
+++ src/status_im/translations/en.cljs
@@ -58,7 +58,7 @@

    ;;home
    :home                                 "Home"
-   :no-recent-chats                      "There are no recent Chats or DApps here yet.\nUse the “Plus” button to see the list of Dapps or discover people to chat with"
+   :no-recent-chats                      "There are no recent Chats or DApps here yet. Use the “Plus” button to see the list of Dapps or discover people to chat with."
    :welcome-to-status                    "Welcome to Status"
    :welcome-to-status-description        "Here you can chat with people in a secure private chat, browse and interact with DApps. Use the “Plus” icon above to explore Status"


(TK-330) Minor simplifications / improvements to test

--- test/puppetlabs/trapperkeeper/shutdown_test.clj
+++ test/puppetlabs/trapperkeeper/shutdown_test.clj
@@ -388,6 +388,8 @@
                       context)
                (stop [this context]
                      (swap! lifecycle-events conj :stop)
+                     ;; request shutdown, which will trigger the shutdown logic
+                     ;; on the main thread.
                      (request-shutdown)
                      (deliver first-stop-begun? true)
                      @stop-should-proceed?
@@ -397,7 +399,11 @@
                {})
           ;; this ensures that the 'main' shutdown logic will be runnable,
           ;; and gives us a way to observe when it has completed.
-          app-main-thread (future (tk/run-app app))]
+          app-main-thread (future (tk/run-app app))
+          shutdown-service (tk-app/get-service app :ShutdownService)]
+
+      ;; no shutdown requested yet
+      (is (nil? (internal/get-shutdown-reason shutdown-service)))

       ;; now we trigger a restart, which will call 'stop' for the first time,
       ;; which will request a shutdown but will block on the stop-should-proceed
@@ -407,17 +413,17 @@
       ;; wait until we know that the shutdown has been requested
       @first-stop-begun?

-      ;; at this point, the app's shutdown-reason-promise should be set, but
-      ;; the main thread should be blocked because our first 'stop' is blocked.
-      (is (realized? (:shutdown-reason-promise @(tk-app/app-context app))))
-      (is (not (realized? app-main-thread)))
+      ;; we want to give the main thread a little time in case it is going to
+      ;; do anything nefarious (as it would have before we consolidated the
+      ;; shutdown logic into the core.async worker loop)
+      (Thread/sleep 100)
+
+      ;; at this point, the app's shutdown-reason-promise should be set
+      (is (not (nil? (internal/get-shutdown-reason shutdown-service))))

       ;; validate that the first three events are as expected (we're still blocked
       ;; in the first 'stop').
-      (let [expected-lifecycle-events [:init :start :stop]]
-        (while (< (count @lifecycle-events) (count expected-lifecycle-events))
-          (Thread/yield))
-        (is (= expected-lifecycle-events @lifecycle-events)))
+      (is (= [:init :start :stop] @lifecycle-events))

       ;; main thread should still be blocked
       (is (not (realized? app-main-thread)))