domain knowledge aquired, finally on the downslope, geez

--- sidecar/src/figwheel_sidecar/config_check/type_check.clj
+++ sidecar/src/figwheel_sidecar/config_check/type_check.clj
@@ -63,12 +63,15 @@
 ;; TODO examine need for initial recursion step
 (defn decompose [type-gen-fn node' s']
   (letfn [(handle-key-type [orig-key predicate-key-name node t]
-            (if (fn? orig-key)
+            (cond
+              (fn? orig-key)
               [[predicate-key-name :?- [node :> t]]
                [predicate-key-name := orig-key]]
-              [[orig-key :- [node :> t]]]))
+              (not (nil? orig-key))
+              [[orig-key :- [node :> t]]]
+              :else []))
           (decomp [node s]
-            (if (nil? s)
+            (if (or (nil? s) (empty? s))
               nil
               (let [[[k' v] & r] s
                     k (prep-key k')
@@ -448,11 +451,14 @@
   (doall (parents-for-type2 'D)))

 (defn get-paths-for-type [root typ]
+  (prn root)
+  (prn typ)
+  (prn (parents-for-type typ))
   (vec
      (mapcat (fn [[ky pt]]
-            (if (= pt root)
-              [[ky]]
-              (mapv #(conj % ky) (get-paths-for-type root pt))))
+               (if (= pt root)
+                 [[ky]]
+                 (mapv #(conj % ky) (get-paths-for-type root pt))))
              (parents-for-type typ))))

 (defn get-paths-for-key [root type ky]
@@ -501,9 +507,11 @@
 (defn max-val [mp]
   (reduce (fn [[k v] [k1 v1]] (if (< v v1) [k1 v1] [k v])) [nil -1] mp))

+
 (defn which-type-wins? [parent-type types]
-  (let [type-map (into {} (filter (comp pos? second)
+  (let [type-map (into {} (filter (comp (partial < (- 0.1)) second)
                                   (frequencies-to-pct (cons parent-type types))))]
+    (prn "prob map" type-map)
     ;; TODO this states all we need is one representation of the type
     ;; this is probably better done outside the function
     ;; or we have a helper function
@@ -668,25 +676,47 @@
                   'Some {:a 1 :c 3}
                   :c ))

+
+(defn miss-matches-type? [actual-type?]
+  (and (not (true? actual-type?))
+       (not (nil? (:alternate-type actual-type?)))))
+
+(defn analyze-for-type-misplacement-helper [root-type type-sig path config collected-path]
+  (when (not-empty type-sig)
+    (let [analysis     (detailed-config-analysis config)
+          actual-type? (analysis-type-matches (last type-sig) analysis)]
+      (prn actual-type?)
+      (if (miss-matches-type? actual-type?)
+        {:Error :wrong-position-for-value
+         :current-path collected-path
+         :expected-type (last type-sig)
+         :value config
+         :path collected-path
+         :actual-type (:alternate-type actual-type?)
+         :correct-paths (get-paths-for-type root-type (:alternate-type actual-type?))}
+        (let [k (last path)]
+          (analyze-for-type-misplacement-helper
+           root-type
+           (butlast type-sig)
+           (butlast path)
+           (get config k)
+           (cons k collected-path)))))))
+
+(defn analyze-for-type-misplacement [root-type {:keys [type-sig path orig-config] :as error}]
+  (analyze-for-type-misplacement-helper root-type type-sig path orig-config '()))
+
 (defn unknown-key-error-helper [root-type parent-type bad-key value error]
-  (let [parent-config-value (error-parent-value error)
-        analysis            (detailed-config-analysis parent-config-value)
-        actual-parent-type? (analysis-type-matches parent-type analysis)]
-    #_(prn root-type actual-parent-type?)
-    #_(pprint/pprint analysis)
-    #_(if (= bad-key :magicl))
-    (if (and (not (true? actual-parent-type?)) (not (nil? (:alternate-type actual-parent-type?))))
-      ;; not parent type we are looking at a misplaced configuration
-      ;; value
-      ;; TODO this is still weak
-      [{:Error :wrong-position-for-value
-        :current-path (-> error :path rest)
-        :expected-type parent-type
-        :value parent-config-value
-        :path (rest (:path error))
-        :actual-type (:alternate-type actual-parent-type?)
-        :correct-paths (get-paths-for-type root-type (:alternate-type actual-parent-type?))}]
-      ;; now we can determing if this is most likely a mispelled key
+  (if-let [error (analyze-for-type-misplacement root-type error)]
+    [error]
+    (let [parent-config-value (error-parent-value error)
+          analysis            (detailed-config-analysis parent-config-value)
+          actual-parent-type? (analysis-type-matches parent-type analysis)]
+      #_(prn root-type actual-parent-type?)
+      (prn "START ----")
+      (prn bad-key)
+      (prn parent-type)
+      (pprint/pprint analysis)
+      (prn "END -----")
       (if-let [mispelled-key-error (misspelled-key? parent-type parent-config-value bad-key analysis)]
         [mispelled-key-error]
         (if-let [misplaced-key-error
@@ -775,16 +805,16 @@
                           (if (neg? pos) 100 pos))) res-groups)))

 (defn type-check-one-error [root-type value]
-    (when-let [results (not-empty (type-checker root-type value {}))]
-      (when-let [[[typ errors] & xs] (not-empty (->> results
+  (when-let [results (not-empty (type-checker root-type value {}))]
+    (when-let [[[typ errors] & xs] (not-empty (->> results
                                                    (map #(assoc % :orig-config value))
                                                    group-and-sort-first-pass-errors))]
-        ;; TODO process one error?
-        (when-let [errors (not-empty (doall (handle-type-error-groupp root-type [typ errors])))]
-          (when-let [[[typ errors] & xs] (not-empty (->> errors
-                                                         (map #(assoc % :orig-config value))
-                                                         group-and-sort-first-pass-errors))]
-            (first errors))))))
+      ;; TODO process one error?
+      (when-let [errors (not-empty (doall (handle-type-error-groupp root-type [typ errors])))]
+        (when-let [[[typ errors] & xs] (not-empty (->> errors
+                                                       (map #(assoc % :orig-config value))
+                                                       group-and-sort-first-pass-errors))]
+          (first errors))))))

 #_(with-schema
   (index-spec
@@ -1137,44 +1167,52 @@

 (defmethod error-help-message :wrong-position-for-value
   [{:keys [key correction correct-paths]}]
-  [:group
-   "The value below "
-   " is most likely in the wrong place in your config."])
+  [:group "The value below is most likely in the wrong place in your config."])

 #_(pp)
 ;; printing

-(defn gen-path [path value]
+(defn format-map [leaf-node]
+  [:group "{"
+   [:nest 2
+    :line
+    leaf-node]
+   "}"])
+
+(defn print-path-helper [[x & xs :as path] leaf-node]
   (if (empty? path)
-    value
-    (let [[x & xs] path]
-      (cond
-        (and (integer? x) (zero? x))
-        [(gen-path xs value)]
-        :else {x (gen-path xs value)}))))
-
-(defn print-path [[x & xs] leaf-node edn]
-   (if (and x (get edn x))
-     (let [v (get edn x)]
-       [:group
-        (str (if (map? edn)
-               (str (pr-str x) " ")
-               "")
-             (if (and (not (map? v)) (integer? (first xs)))
-               "["
-               "{"))
-        (if (map? v)
-          [:nest 2
-           :line
-           (print-path xs leaf-node v)]
-          (print-path xs leaf-node v))
-        (if (and (not (map? v)) (integer? (first xs)))
-          "]"
-          "}")])
-     leaf-node))
-
-#_(pprint-document (print-path2 [:cljsbuild :builds 0 :css-dirs] [:group "hey"] {:cljsbuild {:builds [{:css-dirs []}]}})
-                 {:width 20})
+    leaf-node
+    (let [array? (and (number? x) (zero? x))]
+      [:group
+       (if array? "[" "{")
+       (if array?
+         (print-path-helper xs leaf-node)
+         [:nest 2
+          :line
+          (list
+           (if array? "" [:span [:text (pr-str x)] " "])
+           (print-path-helper xs leaf-node))])
+       (if array? "]" "}")])))
+
+;; print-path ignores the initial wrapping
+(defn print-path [[x & xs :as path] leaf-node]
+  (if (empty? path)
+    leaf-node
+    (let [array? (and (number? x) (zero? x))]
+      (if array?
+      (print-path-helper xs leaf-node)
+      [:group
+       (if array? "" [:span [:text (pr-str x)] " "])
+       (print-path-helper xs leaf-node)]))))
+
+
+
+#_(fipp-format-data {:asdf {:Asdf {:asdf 1 :asdfff 2}}})
+
+
+(print-path [] [:text "3"])
+#_(pprint-document (print-path [:asdf 0 :asdfff :asdf 0 ] [:text "3"] )
+                 {:width 20} )

 (defn blank-document? [x]
   (or (nil? x)
@@ -1186,59 +1224,45 @@
     [:group :break :break]
     [:group :break d :line]))

-(defn print-path-error
-  ([{:keys [path orig-config] :as error} leaf-node document]
+(defn print-path-error [message path leaf-node document]
    [:group
     (color "\n------- Figwheel Configuration Error -------\n" :red)
     :break
-    (error-help-message error)
+    message
     :break
     :break
-    [:nest 2
-     (print-path (reverse
-                  (if (parent-is-sequence? error)
-                    (rest (rest path))
-                    (rest path)))
-                 leaf-node
-                 orig-config)]
+    [:nest 2 (print-path path leaf-node)]
     :break
     (print-document document)])
-  ([error leaf]
-   (print-path-error error leaf "")))
+
+#_(pprint-document (print-path [:cljsbuild :builds 0 :compiler :closure-warnings :const] "5"
+                             (gen-path [:cljsbuild :builds 0 :compiler :closure-warnings :const] "5"))
+                 {:width 20})

 #_(gen-path [:cljsbuild :builds 0 :compiler :closure-warnings :const] 5)
+
 #_(pp)
-(defn print-wrong-path-error
-  ([{:keys [path orig-config correction path correct-paths value] :as error} leaf-node document]
-   [:group
-    (color "\n------- Figwheel Configuration Error -------\n" :red)
-    :break
-    (error-help-message error)
-    :break
-    :break
-    [:nest 2
-     (print-path (reverse (rest path))
-                 leaf-node
-                 orig-config)]
-    :break
-    :break
-    [:group "It should probably be placed here:"]
-    :break
-    :break
-    [:nest 2
-     (let [k (or correction (first path))]
-       (print-path (butlast (first correct-paths))
-                   [:group
-                    (color (pr-str k) :green)
-                    " "
-                    [:nest (+ (count (pr-str k)) 2)
-                     (summerize-value value)]
-                    :line]
-                   (gen-path (first correct-paths) value)))]
-    :break
-    (print-document document)])
-  ([error leaf]
-   (print-path-error error leaf "")))
+(defn print-wrong-path-error [message path leaf-node document correct-path value]
+     [:group
+   (color "\n------- Figwheel Configuration Error -------\n" :red)
+   :break
+   message
+   :break
+   :break
+   [:nest 2
+    (print-path path leaf-node)]
+   :break
+   :break
+   [:group "It should probably be placed here:"]
+   :break
+   :break
+   [:nest 2
+    (print-path correct-path
+                (if (empty? correct-path)
+                  (summerize-value-unwrap-top value)
+                  (summerize-value value)))]
+   :break
+   (print-document document)])

 #_(pp)

@@ -1379,14 +1403,15 @@
       "")))

 (defn summerize-coll [open close fn v]
-  (let [res (vec (concat [:nest (inc (count open))] (interpose :line (take 2 (map fn v)))))]
+  (let [res (vec (cons :align
+                         (list
+                          (concat
+                           (interpose :line (take 2 (map fn v)))
+                           (if (> (count v) 2) [:line "..."] [])))))]
     (vec
-     (concat
-      [:group open " "]
-      [(vec
-        (concat res
-                (if (> (count v) 2) [:line "... " close] [" " close]))) ]
-      ))))
+     (concat [:group open " "]
+             (list res)
+             (list " " close)))))

 (declare summerize-value summerize-term)

@@ -1417,6 +1442,18 @@
     (seq? v) (summerize-seq v)
     :else (pr-str v)))

+(defn summerize-value-unwrap-top [v]
+  (let [res (summerize-value v)]
+    (if (map? v)
+      (nth res 3)
+      res)))
+
+#_(pprint-document (summerize-value-unwrap-top {:aasdfasdfasdf 1
+                                                :basdfasdfasdf 2
+                                                :casdfasdfasdf 2
+                                                :dasdfasdfasdf 2})
+                   {:width 10})
+
 (defn format-key
   ([k] (pr-str k))
   ([k colr] (color (format-key k) colr)))
@@ -1424,123 +1461,293 @@
 (defn format-value
   ([value] (summerize-value value))
   ([value colr] (color (format-value value) colr)))
+
+(defn format-under-message [message]
+  [:group
+   [:line "                             "]
+   (color message :underline :magenta)])

 (defn format-key-value [ky fk fv message]
   [:group
    fk
    " "
    [:nest (inc (count (pr-str ky))) fv]
-   [:line " <- "]
-    (color message :underline :magenta)
-    :line])
+   (format-under-message message)
+   :line])
+

 (defmulti print-error :Error)

 (defmethod print-error :unknown-key [{:keys [key value path type-sig] :as error}]
-  (pprint-document (print-path-error error
-                                     (format-key-value
-                                      key
-                                      (format-key key :red)
-                                      (format-value value)
-                                      (str "^ key " (pr-str key) " not recognized")))
-                   {:width 40}))
-
-(defmethod print-error :missing-required-key [{:keys [path value type-sig] :as error}]
-  (pprint-document (print-path-error error
-                                     [:group
-                                      (color (pr-str (first path)) :red)
-                                      [:line " <- "]
-                                      (color (str "^ required key " (pr-str (first path)) " is missing")
-                                             :underline :magenta)
-                                      :line]
-                                     (document-key (first type-sig) (first path))
-                                     )
-                   {:width 40}))
+  (let [parent-path (reverse (rest path))]
+    (pprint-document (print-path-error (error-help-message error)
+                                       parent-path
+                                       ((if (not-empty parent-path) format-map identity)
+                                        (format-key-value
+                                         key
+                                         (format-key key :red)
+                                         (format-value value)
+                                         (str "^ key " (pr-str key) " not recognized")))
+                                       "")
+                     {:width 40})))
+
+(comment
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nah)})
+                                (spec 'Nah {:a 3})
+                                (requires-keys 'RootMap :wowza))
+                    'RootMap {:asdf 2})
+  )
+
+(defmethod print-error :missing-required-key [{:keys [path value key type-sig] :as error}]
+  (let [parent-path (-> path rest reverse)]
+    (pprint-document
+     (print-path-error (error-help-message error)
+                       parent-path
+                       ((if (not-empty parent-path) format-map identity)
+                        [:group
+                         (color (pr-str key) :red)
+                         [:line "                              "]
+                         (color (str "^ required key " (pr-str key) " is missing")
+                                :underline :magenta)
+                         :line])
+                       (document-key (first type-sig) key))
+                   {:width 40})))
+
+(comment
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nah)})
+                                (spec 'Nah {:a 3})
+                                (requires-keys 'RootMap :wowza)
+                                (requires-keys 'Nah :a))
+                    'RootMap {:wowza {}})
+  )

 (defn failed-predicate [{:keys [path value type-sig orig-config] :as error}]
-  (if (parent-is-sequence? error)
-    (let [orig-config-seq (get-in orig-config (reverse (rest path)))]
-      (pprint-document (print-path-error error
-                                         [:nest 2
-
-                                          (concat
-                                           [:group (format-key (second path))  " [ " ]
-                                           [[:nest (+ 3 (count (str (second path))))
-
-                                             (cons :group
-                                                   (interpose :line (map-indexed
-                                                             #(if (= (first path) %1)
-                                                                (color (pr-str %2) :red)
-                                                                (pr-str %2))
-                                                             orig-config-seq)
-                                                      ))]]
-                                           #_(format-value value :red)
-                                           [" ] "])]
-                                         (document-key (first (rest (rest type-sig))) (second path)))
+  (let [parent-path (-> path rest reverse)]
+    (if (parent-is-sequence? error)
+      (let [orig-config-seq (get-in orig-config parent-path)]
+        (pprint-document (print-path-error (error-help-message error)
+                                           parent-path
+                                           [:nest 2
+
+                                            (concat
+                                             [:group #_(format-key (second path))
+                                              " [ " ]
+                                             [[:align
+                                               (cons :group
+                                                     (interpose :line (map-indexed
+                                                                       #(if (= (first path) %1)
+                                                                          [:group (color (pr-str %2) :red)
+                                                                           (format-under-message "^ is a bad value")]
+                                                                          (pr-str %2))
+                                                                       orig-config-seq)
+                                                                ))]]
+                                             #_(format-value value :red)
+                                             [" ] "])]
+                                           (document-key (first (rest (rest type-sig))) (second path)))
+                         {:width 40}))
+      (pprint-document (print-path-error (error-help-message error)
+                                         parent-path
+                                         ((if (not-empty parent-path) format-map identity)
+                                          (format-key-value
+                                           (first path)
+                                           (format-key (first path) :bold)
+                                           (format-value value :red)
+                                           (str "^ key " (pr-str (first path)) " has wrong value")))
+                                         (document-key (first (rest type-sig)) (first path)))
                        {:width 40}))
-    (pprint-document (print-path-error error
-                                       (format-key-value
-                                        (first path)
-                                        (format-key (first path) :bold)
-                                        (format-value value :red)
-                                        (str "^ key " (pr-str (first path)) " has wrong value"))
-                                       (document-key (first (rest type-sig)) (first path)))
-                     {:width 40})))
+
+    )
+  )
+
+(comment
+
+  (print-one-error  (index-spec (spec 'RootMap {:wowza 3 #_(ref-schema 'Nah)})
+                                (spec 'Nah {:a 3})
+                                #_(requires-keys 'RootMap :wowza)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap {:wowza {:a 4}})
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nah)})
+                                (spec 'Nah [string?])
+                                #_(requires-keys 'RootMap :wowza)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap {:wowza ["Asdf" 1 "asdf" ]})
+  )
+
+

 (defmethod print-error :failed-predicate [error] (failed-predicate error))
 (defmethod print-error :combined-failed-predicate [error] (failed-predicate error))

 (defmethod print-error :should-not-be-empty [{:keys [path value type-sig orig-config] :as error}]
-  (pprint-document (print-path-error error
-                                     (format-key-value
-                                      (first path)
-                                      (format-key (first path) :bold)
-                                      (format-value value :red)
-                                      (str "^ key " (pr-str (first path)) " should not be empty"))
-                                     (document-key (first type-sig) (first path)))
-                   {:width 40}))
-
-(defmethod print-error :misplaced-key [{:keys [key correct-paths correct-type orig-error orig-config type-sig] :as error}]
-  (pprint-document (print-wrong-path-error
-                    error
-                    (format-key-value
-                     key
-                     (format-key key :red)
-                     (format-value (:value orig-error))
-                     (str "^ key " (format-key key) " is on the wrong path"))
-                    (document-key (first correct-type) key))
-                   {:width 40}))
-
-(defmethod print-error :misspelled-misplaced-key [{:keys [key correct-paths correction correct-type orig-error orig-config type-sig] :as error}]
-  (pprint-document (print-wrong-path-error
-                    error
-                    (format-key-value
-                     key
-                     (format-key key :red)
-                     (format-value (:value orig-error))
-                     (str "^ key " (format-key key) " is mispelled and on the wrong path"))
-                    (document-key (first correct-type) correction))
-                   {:width 40}))
-
-(defmethod print-error :wrong-position-for-value [{:keys [key value correct-paths correct-type orig-error orig-config type-sig] :as error}]
-  (pprint-document (print-wrong-path-error
-                    (assoc error :correction (first (first correct-paths)))
-                    [:group
-                     (format-value value :bold)
-                     [:line " <- "]
-                     (str "^ value is in the wrong place")]
-                    (document-key (first correct-type) (first (first correct-paths))))
-                   {:width 40}))
+  (let [parent-path (-> path rest reverse)
+        ky          (first path)]
+    (pprint-document (print-path-error (error-help-message error)
+                                       parent-path
+                                       ((if (not-empty parent-path) format-map identity)
+                                        (format-key-value
+                                         ky
+                                         (format-key ky :bold)
+                                         (format-value value :red)
+                                         (str "^ key " (pr-str ky) " should not be empty")))
+                                       (document-key (first type-sig) ky))
+                     {:width 40})))
+
+(comment
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nah)})
+                                (spec 'Nah {:a [string?]})
+                                (assert-not-empty 'Nah :a)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap {:wowza {:a []}})
+  )
+
+(defmethod print-error :misplaced-key [{:keys [key path correct-paths correct-type value orig-error orig-config type-sig] :as error}]
+  (let [parent-path (reverse (rest path))
+        correct-path (first correct-paths)
+        correct-key  (last correct-path)]
+    (pprint-document
+     (print-wrong-path-error
+      (error-help-message error)
+      parent-path
+      ((if (not-empty parent-path) format-map identity)
+       (format-key-value
+        key
+        (format-key key :red)
+        (format-value value)
+        (str "^ key " (format-key key) " is on the wrong path")))
+      (document-key (first correct-type) key)
+      correct-path
+      value)
+     {:width 40})))
+
+(comment
+
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nahbu)
+                                                :asdf {}})
+                                (spec 'Nah {:aasdfasdfasdf 1
+                                            :basdfasdfasdf 2
+                                            :casdfasdfasdf 3
+                                            })
+                                (spec 'Nahbu {:nah (ref-schema 'Nah)
+                                              :bleh {}})
+                                #_(assert-not-empty 'Nah :a)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap
+                    {:wowza {:nah {
+                                  :aasdfasdfasdf 1
+                                  :basdfasdfasdf 2
+                                  :bleh {:asfd 1}
+                                  }}
+                     })
+
+  )
+
+(defmethod print-error :misspelled-misplaced-key
+  [{:keys [key correct-paths correction path value correct-type orig-error orig-config type-sig] :as error}]
+  (let [parent-path (reverse (rest path))
+        correct-path (first correct-paths)
+        correct-key  correction]
+    (pprint-document (print-wrong-path-error
+                      (error-help-message error)
+                      parent-path
+                      ((if (not-empty parent-path) format-map identity)
+                       (format-key-value
+                        key
+                        (format-key key :red)
+                        (format-value value)
+                        (str "^ key " (format-key key) " is mispelled and on the wrong path")))
+                      (document-key (first correct-type) correction)
+                      correct-path
+                      value)
+                     {:width 40})))
+
+(comment
+'WORK
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nahbu)
+                                                :asdf {}})
+                                (spec 'Nah {:aasdfasdfasdf 1
+                                            :basdfasdfasdf 2
+                                            :casdfasdfasdf 3
+                                            })
+                                (spec 'Nahbu {:nah (ref-schema 'Nah)
+                                              :bleh {}})
+                                #_(assert-not-empty 'Nah :a)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap
+                    {:wowza {:nah {
+                                  :aasdfasdfasdf 1
+                                  :basdfasdfasdf 2
+                                  :blehh {:asfd 1}
+                                  }}
+                     })
+
+
+
+  )
+
+
+(defmethod print-error :wrong-position-for-value
+  [{:keys [key value path correct-paths correct-type orig-error orig-config type-sig] :as error}]
+#_[message path leaf-node document correct-path value]
+  (let [parent-path (reverse path)
+        correct-path (first correct-paths)
+        correct-key  (last correct-path)]
+    (pprint-document
+     (print-wrong-path-error
+      (error-help-message error)
+      parent-path
+      [:align
+       (list
+        (format-value value :bold)
+        [:line "                           "]
+        (str "^ value is in the wrong place"))]
+      (document-key (first correct-type) correct-key)
+      correct-path
+      value)
+   {:width 40})))
+
+
+(comment
+
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nahbu)
+                                                :asdf {}})
+                                (spec 'Nah {:aasdfasdfasdf 1
+                                            :basdfasdfasdf 2
+                                            :casdfasdfasdf 3
+                                            })
+                                (spec 'Nahbu {:nah (ref-schema 'Nah)})
+                                #_(assert-not-empty 'Nah :a)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap
+                    {:asdf {:aasdfasdfasdf 1
+                            :basdfasdfasdf 2
+                            :casdfasdfasdf 3
+                            }
+                      })
+  )
+
+

 (defmethod print-error :failed-key-predicate [{:keys [key value orig-error orig-config type-sig path] :as error}]
-  (pprint-document (print-path-error error
-                                     (format-key-value
-                                      key
-                                      (format-key key :red)
-                                      (format-value value)
-                                      (str "^ key " (pr-str key) " failed key predicate"))
-                                     (document-key (first (rest type-sig)) (first (rest path))))
-                   {:width 40}))
+  (let [parent-path (-> path rest reverse)]
+    (pprint-document (print-path-error (error-help-message error)
+                                       parent-path
+                                       ((if (not-empty parent-path) format-map identity)
+                                        (format-key-value
+                                         key
+                                         (format-key key :red)
+                                         (format-value value)
+                                         (str "^ key " (pr-str key) " failed key predicate")))
+                                       ;; document-parent
+                                       (document-key (first (rest type-sig)) (first (rest path))))
+                     {:width 40})))
+
+(comment
+  (print-one-error  (index-spec (spec 'RootMap {integer? (ref-schema 'Nah)})
+                                (spec 'Nah {string? [string?]})
+                                #_(assert-not-empty 'Nah :a)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap {:w 1})
+  )

 (defn document-all [parent-typ all-keys]
   (doall
@@ -1551,15 +1758,26 @@
                     (fn [ky]
                       (document-key parent-typ ky)) all-keys))))))

-(defmethod print-error :misspelled-key [{:keys [key corrections orig-error orig-config type-sig] :as error}]
-  (pprint-document (print-path-error error
-                                     (format-key-value
-                                      key
-                                      (format-key key :red)
-                                      (format-value (:value orig-error))
-                                      (str "^ key " (pr-str key) " is spelled wrong"))
-                                     (document-all (first type-sig) corrections))
-                   {:width 40}))
+(defmethod print-error :misspelled-key [{:keys [key corrections orig-error value orig-config type-sig path] :as error}]
+  (let [parent-path (-> path rest reverse)]
+    (pprint-document (print-path-error (error-help-message error)
+                                       parent-path
+                                       ((if (not-empty parent-path) format-map identity)
+                                        (format-key-value
+                                         key
+                                         (format-key key :red)
+                                         (format-value value)
+                                         (str "^ key " (pr-str key) " is spelled wrong")))
+                                       (document-all (first type-sig) corrections))
+                     {:width 40})))
+
+(comment
+  (print-one-error  (index-spec (spec 'RootMap {:wowza (ref-schema 'Nah)})
+                                (spec 'Nah {:nada [string?]})
+                                #_(assert-not-empty 'Nah :a)
+                                #_(requires-keys 'Nah :a))
+                    'RootMap {:wowza {:nad []}})
+  )

 (defn print-errors [rules root config]
   (with-schema rules


added p25.clj

added p25.clj

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/drcabana/euler-fp.git/'


[WM] add single-arity subscription read fns

They use the latest db value.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-notification-works.git/'


add nested stack support (#26)

add nested stack support (#26)

error: pathspec 'src/crucible/aws/cloudformation.clj' did not match any file(s) known to git

--- src/crucible/aws/cloudformation.clj
+++ src/crucible/aws/cloudformation.clj
@@ -0,0 +1,16 @@
+(ns crucible.aws.cloudformation
+  (:require [clojure.spec :as s]
+            [crucible.resources :refer [resource-factory]]
+            [crucible.encoding.keys :refer [->key]]
+            [crucible.values :refer [spec-or-ref]]))
+
+(defmethod ->key :template-url [_] "TemplateURL")
+
+(s/def ::parameters (s/keys))
+
+(s/def ::template-url (spec-or-ref string?))
+
+(s/def ::stack (s/keys ::req [::template-url ::parameters]))
+
+(def stack (resource-factory "AWS::CloudFormation::Stack" ::stack))
+


Added Syllables problem.

Added Syllables problem.

error: pathspec 'src/clojush/problems/software/syllables.clj' did not match any file(s) known to git

--- src/clojush/problems/software/syllables.clj
+++ src/clojush/problems/software/syllables.clj
@@ -0,0 +1,196 @@
+;; syllables.clj
+;; Tom Helmuth, thelmuth@cs.umass.edu
+;;
+;; Problem Source: Program Repair Benchmark Paper (add citation later)
+;;
+;; Given a string (max length 20, containing symbols, spaces, digits, and
+;; lowercase letters), count the number of occurances of vowels (a,e,i,o,u,y)
+;; in the string and print that number as X in "The number of syllables is X"
+;;
+;; input stack has the input string
+
+(ns clojush.problems.software.syllables
+  (:use clojush.pushgp.pushgp
+        [clojush pushstate interpreter random util globals]
+        clojush.instructions.tag
+        clojure.math.numeric-tower
+        ))
+
+;; Define test cases
+(defn syllables-input
+  "Makes a Syllables input of length len."
+  [len]
+  (apply str
+         (repeatedly len
+                     #(if (< (lrand) 0.2)
+                        (lrand-nth "aeiouy")
+                        (lrand-nth (map char (concat (range 32 65) (range 91 127))))))))
+
+; Atom generators
+(def syllables-atom-generators
+  (concat (list
+            "The number of syllables is "
+            \a
+            \e
+            \i
+            \o
+            \u
+            \y
+            "aeiouy"
+            ;;; end constants
+            (fn [] (lrand-nth (concat [\newline \tab] (map char (range 32 127))))) ;Visible character ERC
+            (fn [] (syllables-input (lrand-int 21))) ;String ERC
+            ;;; end ERCs
+            (tag-instruction-erc [:exec :integer :boolean :string :char] 1000)
+            (tagged-instruction-erc 1000)
+            ;;; end tag ERCs
+            'in1
+            ;;; end input instructions
+            )
+          (registered-for-stacks [:integer :boolean :string :char :exec :print])))
+
+
+;; A list of data domains for the problem. Each domain is a vector containing
+;; a "set" of inputs and two integers representing how many cases from the set
+;; should be used as training and testing cases respectively. Each "set" of
+;; inputs is either a list or a function that, when called, will create a
+;; random element of the set.
+(def syllables-data-domains
+  [[(list "", "a", "v", "4", "o", " ", "aei", "ouy", "chf", "quite", "a r e9j>"
+          "you are many yay yea"
+          (apply str (repeat 20 \s))
+          (apply str (repeat 20 \o))
+          (apply str (take 20 (cycle (list \w \i \space))))
+          (apply str (take 20 (cycle (list \x \space \y \space))))
+          (apply str (take 20 (cycle (list \e \i \o \y))))) 17 0] ;; Hand-chosen edge cases
+   [(fn [] (syllables-input (inc (lrand-int 20)))) 83 1000]
+   ])
+
+
+(defn test-and-train-data-from-domains
+  "Takes a list of domains and creates a set of (random) train inputs and a set of test
+   inputs based on the domains. Returns [train test]. A program should not
+   be considered a solution unless it is perfect on both the train and test
+   cases."
+  [domains]
+  (apply mapv concat (map (fn [[input-set n-train n-test]]
+                            (if (fn? input-set)
+                              (vector (repeatedly n-train input-set)
+                                      (repeatedly n-test input-set))
+                              (vector (if (>= n-train (count input-set))
+                                        input-set
+                                        (take n-train (shuffle input-set)))
+                                      (if (>= n-test (count input-set))
+                                        input-set
+                                        (take n-test (shuffle input-set))))))
+                          domains)))
+
+;;Can make syllables test data like this:
+;(test-and-train-data-from-domains syllables-data-domains)
+
+; Helper function for error function
+(defn syllables-test-cases
+  "Takes a sequence of inputs and gives IO test cases of the form
+   [input output]."
+  [inputs]
+  (map (fn [in]
+         (vector in
+                 (str "The number of syllables is " (count (filter #(some #{%} "aeiouy") in)))))
+       inputs))
+
+; Define error function. For now, each run uses different random inputs
+(defn syllables-error-function
+  "Returns the error function for the Syllables problem. Takes as
+   input Syllables data domains."
+  [data-domains]
+  (let [[train-cases test-cases] (map #(sort-by (comp count first) %)
+                                      (map syllables-test-cases
+                                           (test-and-train-data-from-domains data-domains)))]
+    (when true ;; Change to false to not print test cases
+      (doseq [[i case] (map vector (range) train-cases)]
+        (println (format "Train Case: %3d | Input/Output: %s" i (str case))))
+      (doseq [[i case] (map vector (range) test-cases)]
+        (println (format "Test Case: %3d | Input/Output: %s" i (str case)))))
+    (fn the-actual-syllables-error-function
+      ([program]
+        (the-actual-syllables-error-function program :train))
+      ([program data-cases] ;; data-cases should be :train or :test
+        (the-actual-syllables-error-function program data-cases false))
+      ([program data-cases print-outputs]
+        (let [behavior (atom '())
+              errors (flatten
+                       (doall
+                         (for [[input correct-output] (case data-cases
+                                                                   :train train-cases
+                                                                   :test test-cases
+                                                                   [])]
+                           (let [final-state (run-push program
+                                                       (->> (make-push-state)
+                                                         (push-item input :input)
+                                                         (push-item "" :output)))
+                                 printed-result (stack-ref :output 0 final-state)]
+                             (when print-outputs
+                               (println (format "\n| Correct output: %s\n| Program output: %s" (pr-str correct-output) (pr-str printed-result))))
+                             ; Record the behavior
+                             (when @global-print-behavioral-diversity
+                               (swap! behavior conj printed-result))
+                             ; Error is Levenshtein distance and, if ends in an integer, distance from correct integer
+                             (vector
+                               (levenshtein-distance correct-output printed-result)
+                               (if-let [num-result (re-find #"-?\d+$" printed-result)]
+                                 (abs (- (Integer/parseInt (re-find #"-?\d+$" correct-output))
+                                         (Integer/parseInt num-result))) ;distance from correct integer
+                                 1000)
+                             )))))]
+          (when @global-print-behavioral-diversity
+            (swap! population-behaviors conj @behavior))
+          errors)))))
+
+(defn syllables-report
+  "Custom generational report."
+  [best population generation error-function report-simplifications]
+  (let [best-program (not-lazy (:program best))
+        best-test-errors (error-function best-program :test)
+        best-total-test-error (apply +' best-test-errors)]
+    (println ";;******************************")
+    (printf ";; -*- Syllables problem report - generation %s\n" generation)(flush)
+    (println "Test total error for best:" best-total-test-error)
+    (println (format "Test mean error for best: %.5f" (double (/ best-total-test-error (count best-test-errors)))))
+    (when (zero? (:total-error best))
+      (doseq [[i error] (map vector
+                             (range)
+                             best-test-errors)]
+        (println (format "Test Case  %3d | Error: %d" i error))))
+    (println ";;------------------------------")
+    (println "Outputs of best individual on training cases:")
+    (error-function best-program :train true)
+    (println ";;******************************")
+    )) ;; To do validation, could have this function return an altered best individual
+       ;; with total-error > 0 if it had error of zero on train but not on validation
+       ;; set. Would need a third category of data cases, or a defined split of training cases.
+
+
+; Define the argmap
+(def argmap
+  {:error-function (syllables-error-function syllables-data-domains)
+   :atom-generators syllables-atom-generators
+   :max-points 800
+   :max-points-in-initial-program 400
+   :evalpush-limit 1600
+   :population-size 1000
+   :max-generations 300
+   :parent-selection :lexicase
+   :genetic-operator-probabilities {:alternation 0.2
+                                    :uniform-mutation 0.2
+                                    :uniform-close-mutation 0.1
+                                    [:alternation :uniform-mutation] 0.5
+                                    }
+   :alternation-rate 0.01
+   :alignment-deviation 10
+   :uniform-mutation-rate 0.01
+   :problem-specific-report syllables-report
+   :print-behavioral-diversity true
+   :report-simplifications 0
+   :final-report-simplifications 5000
+   ;:max-error 1
+   })


fixed cljeval for irc

fixed cljeval for irc

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/m1dnight/a-slack-and-irc-bot.git/'


solved fp challange

solved fp challange

error: pathspec 'src/hackerrank/fp/filter-position.clj' did not match any file(s) known to git

--- src/hackerrank/fp/filter-position.clj
+++ src/hackerrank/fp/filter-position.clj
@@ -0,0 +1,16 @@
+;; Filter Positions in a List
+;; https://www.hackerrank.com/challenges/fp-filter-positions-in-a-list
+
+(def input [2 5 3 4 6 7 9 8])
+
+(->> input
+     (map-indexed vector)
+     (filter #(odd? (first %)))
+     (map second))
+
+;; HackerRank copy-paste
+(fn [input]
+  (->> input
+     (map-indexed vector)
+     (filter #(odd? (first %)))
+     (map second)))


Fix NPE caused by shuffle bug

Fix NPE caused by shuffle bug

--- src/edu/berkeley/ai/angelic/hierarchies/offline_algorithms.clj
+++ src/edu/berkeley/ai/angelic/hierarchies/offline_algorithms.clj
@@ -120,7 +120,7 @@
 		     (concat-solutions
 		      (map #(new-hierarchical-forward-search-id % prune? hla-map depths)
 			   (alts/decompose-plan next))))
-		   (do (doseq [ref (util/shuffle (search/immediate-refinements next))]
+		   (do (doseq [ref (util/shuffle (vec (search/immediate-refinements next)))]
 			 (queues/pq-add! pq (assoc ref :depth (inc (:depth next))) 0))
 		       (recur)))))))))
     depths))))


Simplified util/ctx

Simplified util/ctx

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/physion/ovation-webapi.git/'


Add cors handler.

Add cors handler.

--- src/uxbox/frontend/routes.clj
+++ src/uxbox/frontend/routes.clj
@@ -26,16 +26,16 @@
     (-> (sz/encode body :json)
         (http/ok {:content-type "application/json"}))))

-(defn- redirect-to-api
-  "Endpoint that just redirect to the /api endpoint."
-  [context]
-  (http/see-other "/api"))
-
 (defn- authorization
   [{:keys [identity] :as context}]
   (if identity
     (ct/delegate {:identity (UUID/fromString (:id identity))})
     (http/forbidden (ufc/rsp {:message "Forbidden"}))))
+
+(def cors-conf
+  {:origin "*"
+   :max-age 3600
+   :allow-headers ["X-Requested-With", "Content-Type"]})

 (defn app
   []
@@ -45,9 +45,12 @@
     (ct/routes
      [[:any (cauth/auth backend)]
       [:any (cmisc/autoreloader)]
+      [:get "api" #'welcome-api]
       [:prefix "api"
+       [:any (cmisc/cors cors-conf)]
        [:any (cparse/body-params)]
        [:error #'ufe/handler]
+
        [:post "auth/token" #'ufa/login]
        [:any #'authorization]

@@ -61,7 +64,4 @@
        [:put "pages/:id" #'ufp/page-update]
        [:delete "pages/:id" #'ufp/page-delete]
        [:post "pages" #'ufp/page-create]
-       [:get "pages" #'ufp/page-list]
-
-       [:get "" #'welcome-api]]
-      [:get "" #'redirect-to-api]])))
+       [:get "pages" #'ufp/page-list]]])))


(PDB-2231) Add dump-heap to save mem info via jmap

error: pathspec 'test/puppetlabs/puppetdb/testutils/mem.clj' did not match any file(s) known to git

--- test/puppetlabs/puppetdb/testutils/mem.clj
+++ test/puppetlabs/puppetdb/testutils/mem.clj
@@ -0,0 +1,27 @@
+(ns puppetlabs.puppetdb.testutils.mem
+  (:require [clojure.java.shell :as shell])
+  (:import [java.lang.management ManagementFactory]
+           [java.nio.file Files NoSuchFileException]))
+
+(def getpid
+  "Returns the integer PID of the current process."
+  (let [pid (atom nil)]
+    (fn []
+      (if-let [p @pid]
+        p
+        (reset! pid (->> (ManagementFactory/getRuntimeMXBean)
+                         .getName
+                         (re-find #"[0-9]+")
+                         Integer/parseInt))))))
+
+(defn dump-heap [filename]
+  "Dumps the current heap to filename via jmap."
+  (try
+    ;; Because jmap quietly does nothing if the file exists.
+    (-> filename java.io.File. .toPath Files/delete)
+    (catch NoSuchFileException ex
+      true))
+  (assert (zero?
+           (:exit (shell/sh "jmap"
+                            (str "-dump:live,format=b,file=" filename)
+                            (str (getpid)))))))


Added smallvariant synthetic problem.

Added smallvariant synthetic problem.

error: pathspec 'src/clojush/problems/synthetic/smallvariant.clj' did not match any file(s) known to git

--- src/clojush/problems/synthetic/smallvariant.clj
+++ src/clojush/problems/synthetic/smallvariant.clj
@@ -0,0 +1,33 @@
+;; smallvariant.clj
+;; A problem for Clojush, a Push/PushGP system written in Clojure
+;; Lee Spector, lspector@hampshire.edu, 2015
+
+;; NOTE: "Success" is not possible on this problem, unless a non-default
+;; error threshold is used.
+
+;; This problem exists to evolve small genomes that are recursively variant
+;; in the context of autoconstruction. The single error value is the size
+;; of the genome + 1 if the genome is recursively variant, or a large
+;; penalty otherwise.
+
+(ns clojush.problems.synthetic.smallvariant
+  (:use [clojush.pushgp.pushgp]
+        [clojush.util]
+        [clojush.pushgp.genetic-operators]))
+
+(defn smallvariant-error
+  "Returns a vector containing a single error which will be the
+  size of the genome + 1 if the genome is recursively variant, or a large
+  penalty otherwise."
+  [individual]
+  (if (recursively-variant? (:genome individual) @push-argmap)
+    [(inc (count (:genome individual)))]
+    [1000000]))
+
+(def argmap
+  {:error-function smallvariant-error
+   :atom-generators []
+   :autoconstructive true
+   :report-simplifications 0
+   :pass-individual-to-error-function true})
+


Finish small cleanup I started in lookup-test

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/electorate-works.git/'


print debugging

print debugging

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AustinC/persistent-internals.git/'


added (eval-scheme str-exp). Only available in clojure

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/parenode/clojure-cup-2015.git/'


Add :voter-info-timestamp to vote-tomorrow context

...so we can make decisions about whether or not to refresh it at send
time.


gen-class stub

gen-class stub

error: pathspec 'src/c4_arena/players/ConnectFourGameTromp.clj' did not match any file(s) known to git

--- src/c4_arena/players/ConnectFourGameTromp.clj
+++ src/c4_arena/players/ConnectFourGameTromp.clj
@@ -0,0 +1,5 @@
+(ns c4-arena.players.ConnectFourGameTromp
+  (:gen-class))
+
+(defn -toString  [this]
+  "Hello, World!")


Datan basic-date-time-no-ms formatua erabili

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lnmnd/magnet.zer.git/'


Storm-456: activate response redirect should have encoded id.

--- storm-core/src/clj/backtype/storm/ui/core.clj
+++ storm-core/src/clj/backtype/storm/ui/core.clj
@@ -908,7 +908,7 @@
         (assert-authorized-user servlet-request "activate" (topology-config id))
         (.activate nimbus name)
         (log-message "Activating topology '" name "'")))
-    (resp/redirect (str "/api/v1/topology/" id)))
+    (resp/redirect (str "/api/v1/topology/" (url-encode id))))
   (POST "/api/v1/topology/:id/deactivate" [:as {:keys [cookies servlet-request]} id]
     (with-nimbus nimbus
       (let [tplg (.getTopologyInfo ^Nimbus$Client nimbus id)


filter return values of create vertex and edge actions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/colophon/clarango.git/'


Updated uniprot protein enters gene mapping rule to work with ccp ext ontology

error: pathspec 'resources/rules/post_identifier_merge/ice_to_bio/uniprot_protein_entrez_gene_mapping.clj' did not match any file(s) known to git

--- resources/rules/post_identifier_merge/ice_to_bio/uniprot_protein_entrez_gene_mapping.clj
+++ resources/rules/post_identifier_merge/ice_to_bio/uniprot_protein_entrez_gene_mapping.clj
@@ -0,0 +1,32 @@
+;; -------------------------------------------------------
+;; --------- Uniprot Protein Entrez Gene Mapping ---------
+;; -------------------------------------------------------
+`{:name "uniprot-protein-entrez-gene-mapping"
+   :description "This rule maps uniprot proteins to entrez genes"
+   :head (
+          ;; map proteins to genes
+          (?/protein kso/has_indirect_template ?/gene)
+
+          ;; create has indirect template restriction
+          (?/indirect_template_restriction rdf/type owl/Restriction)
+          (?/indirect_template_restriction owl/onProperty kso/has_indirect_template)
+          (?/indirect_template_restriction owl/someValuesFrom ?/gene)
+          (?/protein rdfs/subClassOf ?/indirect_template_restriction))
+
+    :body ((?/record rdf/type ccp/IAO_EXT_0000235) ; ccp:UniProt_identifier_mapping_record
+           (?/record obo/BFO_0000051 ?/field_1_field_value) ; BFO:has_part
+           (?/field_1_field_value rdf/type ccp/IAO_EXT_0000239) ; ccp:UniProt_identifier_mapping_record__UniProt_accession_identifier_field_value
+           (?/field_1_field_value rdf/type ?/field_1_ice_id)
+           (?/field_1_ice_id obo/IAO_0000219 ?/protein) ; IAO:denotes
+
+           ;; retrieve the external exact match identifier
+           (?/record obo/BFO_0000051 ?/field_2_field_value) ; BFO:has_part
+           (?/field_2_field_value rdf/type ccp/IAO_EXT_0000242) ; ccp:UniProt_identifier_mapping_record__Entrez_gene_identifier_field_value
+           (?/field_2_field_value rdf/type ?/field_2_ice_id)
+           (?/field_2_ice_id obo/IAO_0000219 ?/gene)) ; IAO:denotes
+
+    :reify ([?/indirect_template_restriction1 {:ln (:restriction)
+                   :ns "ccp" :prefix "R_"}])
+
+    :options {:magic-prefixes [["franzOption_clauseReorderer" "franz:identity"]]}
+}


Added more aggressive image compression

Added more aggressive image compression

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/hudren/ebook-novel.git/'


add feed component

add feed component

error: pathspec 'src/ca_recipe/components/feed.clj' did not match any file(s) known to git

--- src/ca_recipe/components/feed.clj
+++ src/ca_recipe/components/feed.clj
@@ -0,0 +1,13 @@
+(ns ca-recipe.components.feed
+  :require [com.stuartsierra.component :as component])
+
+(defrecord Feed [auth status msg-chan response-chan]
+  component/Lifecicle
+  (start [component]
+    (reset! (:status component) :running)
+    (process-messages status msg-chan)
+    (handle-responses status response-chan)
+    component)
+  (stop [component]
+    (reset! (:status component) :stopoed)
+    component))


Deleted obsolete comment

Deleted obsolete comment

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/leif47/immutabledb-experimental.git/'


temporarily use clojure.tools.analyzer.jvm/empty-env to bootstrap analyzer

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aamedina/clojure.llvm.git/'


Added clojure/cljsearch.clj

Added clojure/cljsearch.clj

error: pathspec 'clojure/cljsearch.clj' did not match any file(s) known to git

--- clojure/cljsearch.clj
+++ clojure/cljsearch.clj
@@ -0,0 +1,260 @@
+;;; search.clj: Recursive file search utility
+
+;; by Cary Clark
+;; April 10, 2010
+
+(ns search
+  #^{:author "Cary Clark",
+     :doc "Recursive file search utility"}
+  (:import (java.io File)
+           (java.util.jar JarFile)
+           (java.util.zip ZipFile))
+  (:use [clojure.java.io :only (reader)])
+  (:use [elocale.file :as file])
+  (:use [elocale.utils :as utils]))
+
+(def DEFAULT-DIR-FILTER-PATTERNS  '(#"^\\.svn" #"^CVS$"))
+(def DEFAULT-FILE-FILTER-PATTERNS '(#"^\\.DS_Store$"))
+
+(def OPTIONS
+  [{:short "1", :long "firstmatch", :arg false, :desc "show only the first match for a file+search combination"}
+   {:short "a", :long "allmatches", :arg false, :desc "show all matches"}
+   {:short "b", :long "search-binary", :arg false, :desc "include binary files in search"}
+   {:short "B", :long "no-search-binary", :arg false, :desc "do NOT include binary files in search"}
+   {            :long "filelist", :arg false, :desc "print the list of unique files with matches"}
+   {:short "f", :long "filenamepattern", :arg true, :desc "regex pattern for file name to search"}
+   {:short "F", :long "no-filenamepattern", :arg true, :desc "regex pattern for file name NOT to search"}
+   {            :long "linelist", :arg false, :desc "print the list of unique lines with matches"}
+   {:short "p", :long "printlines", :arg false, :desc "print the lines as they are found"}
+   {:short "P", :long "no-printlines", :arg false, :desc "do not print lines as they are found"}
+   {:short "s", :long "searchstring", :arg true, :desc "a search string (regex pattern)"}
+   {:short "x", :long "ext", :arg true, :desc "a file extension of files to search"}
+   {:short "X", :long "no-ext", :arg true, :desc "a file extension of files NOT to search"}
+   {:short "z", :long "search-compressed", :arg false, :desc "include compressed files in search"}
+   {:short "Z", :long "no-search-compressed", :arg false, :desc "do NOT include compressed files in search"}
+  ])
+
+; struct to hold a search-result
+(defstruct search-result :file :line :linenum :pattern)
+
+; ref to contain the list of search-result structs
+(def search-results (ref []))
+
+(defn printlines? [opts]
+  (get opts :p))
+
+(defn print-search-result
+  "Prints a search-result"
+  [file line linenum pattern opts]
+  (if (> (count (get opts :s)) 1)
+    (print (str pattern ": ")))
+  (if (> linenum 0)
+    (println (format "%s: %d: %s" (get-path file) linenum (.trim line)))
+    (println (format "%s has match" (get-path file)))))
+
+(defn save-search-result
+  "Creates a search-result struct and conjoins it to the search-results vector ref"
+  [file line linenum pattern opts]
+  (dosync
+    (alter search-results conj (struct search-result file line linenum pattern)))
+  (if (printlines? opts)
+    (print-search-result file line linenum pattern opts)))
+
+(defn search-text-file-line [file line linenum opts]
+  (if line
+    (loop [patterns (get opts :s)]
+      (if (> (count (re-seq (first patterns) line)) 0)
+        (save-search-result file line linenum (first patterns) opts))
+      (if (second patterns)
+        (recur
+          (rest patterns))))))
+
+(defn search-reader [rdr file opts]
+  (loop [lines (line-seq rdr)
+         linenum 1]
+    (search-text-file-line file (first lines) linenum opts)
+    (if (second lines)
+      (recur
+        (rest lines)
+        (inc linenum)))))
+
+(defn search-text-file [file opts]
+  ;(println "search-text-file" file)
+  (with-open [rdr (get-reader file)]
+    (search-reader rdr (get-path file) opts)))
+
+(defn search-binary-file [file opts]
+  ;(println "search-binary-file" file)
+  (let [contents (get-contents file)]
+    (loop [patterns (get opts :s)]
+      (if (> (count (re-seq (first patterns) contents)) 0)
+        (save-search-result file "" 0 (first patterns) opts))
+      (if (second patterns)
+        (recur
+          (rest patterns))))))
+
+(defn search-binary? [opts]
+  (get opts :b))
+
+(defn get-zip-file-entries [zipfile opts]
+  (let [entries (filter #(not (.isDirectory %)) (enumeration-seq (.entries zipfile)))]
+    (filter-out-by-ext (concat NOSEARCH-EXTS (get opts :X))
+      (filter-in-by-ext (get opts :x) entries))))
+
+(defn search-zip-file [zipfile opts]
+  (doseq [zipentry (get-zip-file-entries zipfile opts)]
+    (if (text-file? zipentry)
+      (with-open [rdr (reader (.getInputStream zipfile zipentry))]
+        (search-reader rdr (str (.getName zipfile) "[" (.getName zipentry) "]") opts)))))
+
+(defn search-compressed-file [file opts]
+  (cond (has-ext? "zip" file) (search-zip-file (ZipFile. file) opts)
+        (has-ext? "jar" file) (search-zip-file (JarFile. file) opts)))
+
+(defn search-compressed? [opts]
+  (get opts :z))
+
+(defn search-file [file opts]
+  (cond (text-file? file) (search-text-file file opts)
+        (compressed-file? file) (search-compressed-file file opts)
+        ;(binary-file? file) (search-binary-file file opts)))
+        :else (if-not (no-search-file? file) (search-binary-file file opts))))
+
+(defn get-exclude-exts [opts]
+  (let [exclude-exts (set (get opts :X))]
+    (if (> (count exclude-exts) 0)
+      (set
+        (concat
+          exclude-exts
+          NOSEARCH-EXTS
+          (if (search-binary? opts)
+            #{}
+            BINARY-EXTS)
+          (if (search-compressed? opts)
+            #{}
+            COMPRESSED-EXTS)))
+      #{})))
+
+(defn get-include-exts [opts]
+  (let [include-exts (set (get opts :x))]
+    (if (> (count include-exts) 0)
+      (set
+        (concat
+          include-exts
+          (if (search-compressed? opts)
+            COMPRESSED-EXTS
+            #{})))
+      #{})))
+
+(defn filtered-files [startdir opts]
+  (let [files (filter #(file? %) (get-file-seq startdir))
+        exclude-exts (get-exclude-exts opts)
+        include-exts (get-include-exts opts)]
+    ;(println "exclude-exts: " exclude-exts)
+    ;(println "include-exts: " include-exts)
+    (filter-out-by-ext exclude-exts
+      (filter-in-by-ext include-exts
+        (filter-out-by-pattern (get opts :F)
+          (filter-in-by-pattern (get opts :f) files))))))
+
+(defn print-search-results [opts]
+  (loop [patterns (get opts :s)]
+    (println
+      (format
+        "Matches for \"%s\": %d"
+        (first patterns)
+        (count (for [result @search-results :when (= (:pattern result) (first patterns))] result))))
+    (if (second patterns)
+      (recur
+        (rest patterns)))))
+
+(defn search [startdir opts]
+  (doseq [file (filtered-files startdir opts)]
+    (search-file file opts))
+  (print-search-results opts))
+
+(defn indexed [coll] (map vector (iterate inc 0) coll))
+
+(defn get-args-for-opt [coll o]
+  (if ((set coll) o)
+    (vec
+      (set
+        (for [[i elem] (indexed coll)
+              :when (and (= elem o) (> (count coll) (+ i 1)))]
+          (nth coll (inc i)))))
+    []))
+
+(defn get-opts [coll]
+  (let [a (not (contains? (set coll) "-1"))   ; flag for all matches vs. first match only per file
+        b (not (contains? (set coll) "-B"))   ; flag for searching binary files
+        f (vec (map #(re-pattern %) (get-args-for-opt coll "-f"))) ; inclusive file name patterns
+        F (vec (map #(re-pattern %) (get-args-for-opt coll "-F"))) ; exclusive file name patterns
+        filelist (contains? (set coll) "--filelist")   ; flag for listing the files with matches
+        linelist (contains? (set coll) "--linelist")   ; flag for listing the lines with matches
+        p (not (contains? (set coll) "-P"))   ; flag for printing results as found
+        s (vec (map #(re-pattern %) (get-args-for-opt coll "-s"))) ; search strings
+        x (get-args-for-opt coll "-x")        ; the extensions to include
+        X (get-args-for-opt coll "-X")        ; the extensions to exclude
+        z (not (contains? (set coll) "-Z"))]  ; flag for searching compressed files
+    {:a a, :b b, :f f, :F F, :filelist filelist, :linelist linelist, :p p, :s s, :x x, :X X, :z z}))
+
+(defn print-linelist
+  "print the unique list of lines with matches"
+  []
+  (let [lines (sort (set (for [result @search-results :when (not (= (get result :line) ""))] (get result :line))))]
+    (println (format "Lines with matches (%d lines):" (count lines)))
+    (doseq [line lines]
+      (println line))))
+
+(defn print-filelist
+  "print the unique list of files with matches"
+  []
+  (let [files (sort (set (for [result @search-results] (get result :file))))]
+    (println (format "Files with matches (%d files):" (count files)))
+    (doseq [file files]
+      (println file))))
+
+(defn usage []
+  (println "Usage:")
+  (println "search [options] -s <searchstring> <startdir>\n")
+  (println "options:")
+  (let [longest (longest-length (for [option OPTIONS] (get option :long)))
+        format-string (str "%s --%-" (+ 3 longest) "s %s")] ; need $ somewhere
+    (loop [options OPTIONS]
+      (println
+        (format format-string
+          (if (get (first options) :short)
+            (str "-" (get (first options) :short) " |")
+            "    ")
+          (if (get (first options) :arg)
+            (str (get (first options) :long) " x")
+            (get (first options) :long))
+          (get (first options) :desc)))
+      (if (second options)
+        (recur
+          (rest options))
+        (System/exit 0)))))
+
+(defn has-errors [opts startdir]
+  (cond
+    (< (count (get opts :s)) 1) true
+    (contains? (set (concat (vals opts))) startdir) true
+    :else false))
+
+(defn main []
+  (if (or (nil? *command-line-args*) (< (count *command-line-args*) 3))
+    (usage))
+  (let [opts (get-opts (butlast *command-line-args*))
+        startdir (last *command-line-args*)]
+    ;(println (format "*command-line-args*: %s" *command-line-args*))
+    (println (format "opts: %s" opts))
+    ;(println (format "startdir: %s" startdir))
+    (if (has-errors opts startdir)
+      (usage))
+    (search startdir opts)
+    (if (get opts :filelist)
+      (print-filelist))
+    (if (get opts :linelist)
+      (print-linelist))))
+
+(time (main))


even better

even better


Automated testing

Automated testing


Add a namespace to remove deftype boilerplate.

Includes an implementation of maps using alists.

error: pathspec 'src/useful/deftype.clj' did not match any file(s) known to git

--- src/useful/deftype.clj
+++ src/useful/deftype.clj
@@ -0,0 +1,116 @@
+(ns useful.deftype
+  (:use [useful.experimental.delegate :only [parse-deftype-specs emit-deftype-specs]]
+        [useful.map :only [merge-in]])
+  (:require [clojure.string :as s])
+  (:import (clojure.lang IObj MapEntry IPersistentVector
+                         IPersistentMap APersistentMap MapEquivalence)
+           (java.util Map Map$Entry)))
+
+;; to define a new map type, you still must provide:
+;; - IPersistentMap:
+;;   - (.count this)
+;;   - (.valAt this k not-found)
+;;   - (.empty this)
+;;   - (.assoc this k v)
+;;   - (.without this k)
+;;   - (.seq this)
+;;   - recommended but not required: (.entryAt this k)
+;; - IObj
+;;   - (.meta this)
+;;   - (.withMeta this m)
+
+(defmacro defmap [name fields & specs]
+  `(deftype ~name ~fields
+     ~@(emit-deftype-specs
+         (->> (parse-deftype-specs specs)
+              (merge-in (parse-deftype-specs
+                         `(java.util.Map
+                           (size [this#]
+                                 (count this#))
+                           (containsKey [this# k#]
+                                        (contains? this# k#))
+                           (isEmpty [this#]
+                                    (empty? this#))
+                           (keySet [this#]
+                                   (set (keys this#)))
+                           (values [this#]
+                                   (vals this#))
+                           (get [this# k#]
+                                (get this# k#))
+                           (containsValue [this# v#]
+                                          (boolean (seq (filter #(= % v#) (vals this#)))))
+
+                           Object
+                           (toString [this#]
+                                     (str "{" (s/join ", " (for [[k# v#] this#] (str k# " " v#))) "}"))
+                           (equals [this# other#]
+                                   (= this# other#))
+                           (hashCode [this#]
+                                     (APersistentMap/mapHash this#))
+
+                           clojure.lang.IFn
+                           (invoke [this# k#]
+                                   (get this# k#))
+                           (invoke [this# k# not-found#]
+                                   (get this# k# not-found#))
+
+                           MapEquivalence
+
+                           IPersistentMap
+                           (equiv [this# other#]
+                                  (and (instance? Map other#)
+                                       (or (instance? MapEquivalence other#)
+                                           (not (instance? IPersistentMap other#)))
+                                       (= (count this#) (count other#))
+                                       (every? (fn [e#]
+                                                 (let [k# (key e#)
+                                                       o# ^Map other#]
+                                                   (and (.containsKey o# k#)
+                                                        (= (.get o# k#) (val e#)))))
+                                               (seq this#))))
+                           (entryAt [this# k#]
+                                    (let [not-found# (Object.)
+                                          v# (get this# k# not-found#)]
+                                      (when (not= v# not-found#)
+                                        (MapEntry. k# v#))))
+                           (valAt [this# k#]
+                                  (get this# k# nil))
+                           (cons [this# obj#]
+                                 (condp instance? obj#
+                                   Map$Entry (assoc this# (key obj#) (val obj#))
+                                   IPersistentVector (if (= 2 (count obj#))
+                                                       (assoc this# (nth obj# 0) (nth obj# 1))
+                                                       (throw (IllegalArgumentException.
+                                                               "Vector arg to map conj must be a pair")))
+                                   (reduce (fn [m# e#]
+                                             (assoc m# (key e#) (val e#)))
+                                           this# obj#)))
+                           (iterator [this#]
+                                     (clojure.lang.SeqIterator. (seq this#))))))))))
+
+(defmap AList [entries meta]
+  IPersistentMap
+  (count [this]
+         (count entries))
+  (valAt [this k not-found]
+         (if-let [e (find this k)]
+           (val e)
+           not-found))
+  (entryAt [this k]
+           (first (filter #(= k (key %)) entries)))
+  (empty [this]
+         (AList. () meta))
+  (seq [this]
+       (seq entries))
+  (assoc [this k v]
+    (AList. (cons (MapEntry. k v) entries) meta))
+  (without [this k]
+           (AList. (->> entries (remove #(= k (key %)))
+                        (apply list))
+                   meta))
+
+  IObj
+  (meta [this]
+        meta)
+  (withMeta [this meta]
+            (AList. entries meta)))


Liburuekin ere konexioa pasa

Liburuekin ere konexioa pasa


microbench WIP/experiments

microbench WIP/experiments

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/transwarp.git/'


import core implementation

import core implementation

error: pathspec 'src/chartem.clj' did not match any file(s) known to git

--- src/chartem.clj
+++ src/chartem.clj
@@ -0,0 +1,46 @@
+(ns chartem)
+;; Matcher
+;; Match
+;;
+;; is :: a -> Matcher a
+;; allOf [Matcher a] -> Matcher a
+;; runMatcher -> Matcher a -> a -> Match
+
+;; a matcher is a map with three fields, each of whose values are functions:
+;; {:match ;; a -> Bool
+;;  :description :: String
+;;  :describe-mismatch :: a -> String }
+;;
+;;  a match is a map with pass? and message, message will be a string
+;;  if pass? if false
+
+(defn equals [a]
+  {:match (fn [b] (= a b))
+   :description (str "(= " (pr-str a) ")")
+   :describe-mismatch (fn [b] (pr-str b))})
+
+(defn format-message [result]
+  (str "\nExpected: " (:expected result)
+       "\n     but: "
+       (:was result))
+  )
+
+(defn every?
+  [ms]
+  {:match (fn [a] (reduce (fn [x y] (and x y))
+                          (map #((:match %) a) ms)))
+   :description (str "(every? " (clojure.string/join " "
+                                                     (map :description ms)) ")")
+   :describe-mismatch })
+
+(defn run-match
+  [matcher a]
+  (if ((:match matcher) a)
+    {:pass? true}
+    {:pass? false
+     :expected (:description matcher)
+     :was ((:describe-mismatch matcher) a)
+;; "\nExpected: " ++ description m ++ "\n     but: " ++ describeMismatch m a
+     :message (str "\nExpected: " (:description matcher)
+                   "\n     but: "
+                   ((:describe-mismatch matcher) a))}))


as empty will return 0 so don't worry about add nil

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/carolove/clojure-ring-app.git/'


Add debug logging for async transactions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/scheduled-message-works.git/'


Max test.

Max test.

error: pathspec 'test/onyx/windowing/aggregation_max_test.clj' did not match any file(s) known to git

--- test/onyx/windowing/aggregation_max_test.clj
+++ test/onyx/windowing/aggregation_max_test.clj
@@ -0,0 +1,130 @@
+(ns onyx.windowing.aggregation-max-test
+  (:require [clojure.core.async :refer [chan >!! <!! close! sliding-buffer]]
+            [clojure.test :refer [deftest is]]
+            [onyx.plugin.core-async :refer [take-segments!]]
+            [onyx.test-helper :refer [load-config with-test-env]]
+            [onyx.api]))
+
+(def input
+  [{:id 1  :age 21 :event-time #inst "2015-09-13T03:00:00.829-00:00"}
+   {:id 2  :age 12 :event-time #inst "2015-09-13T03:04:00.829-00:00"}
+   {:id 3  :age 3  :event-time #inst "2015-09-13T03:05:00.829-00:00"}
+   {:id 4  :age 64 :event-time #inst "2015-09-13T03:06:00.829-00:00"}
+   {:id 5  :age 53 :event-time #inst "2015-09-13T03:07:00.829-00:00"}
+   {:id 6  :age 52 :event-time #inst "2015-09-13T03:08:00.829-00:00"}
+   {:id 7  :age 24 :event-time #inst "2015-09-13T03:09:00.829-00:00"}
+   {:id 8  :age 35 :event-time #inst "2015-09-13T03:15:00.829-00:00"}
+   {:id 9  :age 49 :event-time #inst "2015-09-13T03:25:00.829-00:00"}
+   {:id 10 :age 37 :event-time #inst "2015-09-13T03:45:00.829-00:00"}
+   {:id 11 :age 15 :event-time #inst "2015-09-13T03:03:00.829-00:00"}
+   {:id 12 :age 22 :event-time #inst "2015-09-13T03:56:00.829-00:00"}
+   {:id 13 :age 83 :event-time #inst "2015-09-13T03:59:00.829-00:00"}
+   {:id 14 :age 60 :event-time #inst "2015-09-13T03:32:00.829-00:00"}
+   {:id 15 :age 35 :event-time #inst "2015-09-13T03:16:00.829-00:00"}])
+
+(def expected-windows
+  [[Double/NEGATIVE_INFINITY Double/POSITIVE_INFINITY 83]])
+
+(def test-state (atom []))
+
+(defn update-atom! [event window-id lower-bound upper-bound state]
+  (swap! test-state conj [lower-bound upper-bound state]))
+
+(def in-chan (atom nil))
+
+(def out-chan (atom nil))
+
+(defn inject-in-ch [event lifecycle]
+  {:core.async/chan @in-chan})
+
+(defn inject-out-ch [event lifecycle]
+  {:core.async/chan @out-chan})
+
+(def in-calls
+  {:lifecycle/before-task-start inject-in-ch})
+
+(def out-calls
+  {:lifecycle/before-task-start inject-out-ch})
+
+(deftest max-test
+  (let [id (java.util.UUID/randomUUID)
+        config (load-config)
+        env-config (assoc (:env-config config) :onyx/id id)
+        peer-config (assoc (:peer-config config) :onyx/id id)
+        batch-size 20
+        workflow
+        [[:in :identity] [:identity :out]]
+
+        catalog
+        [{:onyx/name :in
+          :onyx/plugin :onyx.plugin.core-async/input
+          :onyx/type :input
+          :onyx/medium :core.async
+          :onyx/batch-size batch-size
+          :onyx/max-peers 1
+          :onyx/doc "Reads segments from a core.async channel"}
+
+         {:onyx/name :identity
+          :onyx/fn :clojure.core/identity
+          :onyx/type :function
+          :onyx/max-peers 1
+          :onyx/batch-size batch-size}
+
+         {:onyx/name :out
+          :onyx/plugin :onyx.plugin.core-async/output
+          :onyx/type :output
+          :onyx/medium :core.async
+          :onyx/batch-size batch-size
+          :onyx/max-peers 1
+          :onyx/doc "Writes segments to a core.async channel"}]
+
+        windows
+        [{:window/id :collect-segments
+          :window/task :identity
+          :window/type :global
+          :window/aggregation [:onyx.windowing.aggregation/max :age]
+          :window/window-key :event-time
+          :window/init 0}]
+
+        triggers
+        [{:trigger/window-id :collect-segments
+          :trigger/refinement :accumulating
+          :trigger/on :segment
+          :trigger/fire-all-extents? true
+          :trigger/threshold [15 :elements]
+          :trigger/sync ::update-atom!}]
+
+        lifecycles
+        [{:lifecycle/task :in
+          :lifecycle/calls ::in-calls}
+         {:lifecycle/task :in
+          :lifecycle/calls :onyx.plugin.core-async/reader-calls}
+         {:lifecycle/task :out
+          :lifecycle/calls ::out-calls}
+         {:lifecycle/task :out
+          :lifecycle/calls :onyx.plugin.core-async/writer-calls}]]
+
+    (reset! in-chan (chan (inc (count input))))
+    (reset! out-chan (chan (sliding-buffer (inc (count input)))))
+    (reset! test-state [])
+
+    (with-test-env [test-env [3 env-config peer-config]]
+      (onyx.api/submit-job
+       peer-config
+       {:catalog catalog
+        :workflow workflow
+        :lifecycles lifecycles
+        :windows windows
+        :triggers triggers
+        :task-scheduler :onyx.task-scheduler/balanced})
+
+      (doseq [i input]
+        (>!! @in-chan i))
+      (>!! @in-chan :done)
+
+      (close! @in-chan)
+
+      (let [results (take-segments! @out-chan)]
+        (is (= (into #{} input) (into #{} (butlast results))))
+        (is (= :done (last results)))
+        (is (= expected-windows @test-state))))))


move func def

move func def


core,core* WIP

core,core* WIP


adding ns for backend

adding ns for backend

error: pathspec 'src/cljs/ohds/backend.cljs' did not match any file(s) known to git

--- src/cljs/ohds/backend.cljs
+++ src/cljs/ohds/backend.cljs
@@ -0,0 +1 @@
+(ns ohds.backend)


Update footer links

Update footer links

* link to new contributing wiki page
* link directly to announcements on the maintainers list for news
  instead of the outdated NEWS.md

--- src/clojars/web/common.clj
+++ src/clojars/web/common.clj
@@ -14,7 +14,8 @@
   [:footer.row
    (link-to "https://github.com/ato/clojars-web/wiki/About" "about")
    (link-to "/projects" "projects")
-   (link-to "https://github.com/ato/clojars-web/blob/master/NEWS.md" "news")
+   (link-to "https://github.com/ato/clojars-web/wiki/Contributing" "contribute")
+   (link-to "https://groups.google.com/forum/?fromgroups#!topicsearchin/clojars-maintainers/group:clojars-maintainers$20AND$20subject:ann" "news")
    (link-to "https://github.com/ato/clojars-web/wiki/Contact" "contact")
    (link-to "https://github.com/ato/clojars-web" "code")
    (link-to "/security" "security")


Fix rendering of image primitive childs on android

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/nvbn/rerenderer.git/'


Add retract partner site script (#51)

Add retract partner site script (#51)

* Add dev-src script to retract partner site from partner-works and authz-works databases

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/partner-works.git/'


Add reified-tests example source for testing at the REPL

error: pathspec 'src/test/clojure/lazytest/reified_tests.clj' did not match any file(s) known to git

--- src/test/clojure/lazytest/reified_tests.clj
+++ src/test/clojure/lazytest/reified_tests.clj
@@ -0,0 +1,56 @@
+(ns lazytest.reified-tests
+  (:use (lazytest expect testable runnable-test)))
+
+(def t1 (reify Testable
+	       (get-tests [this]
+			  (list
+			   (reify RunnableTest
+				  (run-tests [this]
+					     (list
+					      (try-expectations this
+								(expect= 1 2)))))))))
+
+(def t2 (reify Testable
+	       (get-tests [this]
+			  (list
+			   (reify RunnableTest
+				  (run-tests [this]
+					     (list
+					      (try-expectations this
+								(expect= 1 1)))))))))
+
+(def t3 (reify Testable
+	       (get-tests [this]
+			  (list
+			   (reify RunnableTest
+				  (run-tests [this]
+					     (list
+					      (try-expectations this
+								(expect-instance java.lang.String :a)))))))))
+
+(def t4 (reify Testable
+	       (get-tests [this]
+			  (list
+			   (reify RunnableTest
+				  (run-tests [this]
+					     (list
+					      (try-expectations this
+								(expect-not= 1 1)))))))))
+
+(def t5 (reify Testable
+	       (get-tests [this]
+			  (list
+			   (reify RunnableTest
+				  (run-tests [this]
+					     (list
+					      (try-expectations this
+								(expect= (/ 1 0) 0)))))))))
+
+(def t6 (reify Testable
+	       (get-tests [this]
+			  (list
+			   (reify RunnableTest
+				  (run-tests [this]
+					     (list
+					      (try-expectations this
+								(expect (< 1 0))))))))))


fixing example dep

fixing example dep

--- example/project.clj
+++ example/project.clj
@@ -4,7 +4,7 @@
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.6.0"]
-                 [org.clojure/clojurescript "0.0-2500"]
+                 [org.clojure/clojurescript "0.0-2496"]
                  [sablono "0.2.16"]
                  [crate "0.2.4"]
                  [jayq "2.4.0"]


Fix for channel coaching question responses.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/couragelabs/coachbot.git/'


add stub test

add stub test

error: pathspec 'test/babel/test/writer.clj' did not match any file(s) known to git

--- test/babel/test/writer.clj
+++ test/babel/test/writer.clj
@@ -0,0 +1,11 @@
+(ns babel.test.writer
+  (:refer-clojure :exclude [test])
+  (:require [babel.writer :as writer]
+            [clojure.string :as string]
+            [clojure.test :refer :all]
+            [clojure.tools.logging :as log]))
+
+(deftest simple
+  (is (= true true)))
+
+


Add sparkline axis, cleanup old render-png functions

--- src/metabase/pulse.clj
+++ src/metabase/pulse.clj
@@ -1,5 +1,8 @@
 (ns metabase.pulse
   (:require [hiccup.core :refer [html]]
+            [clj-time.core :as t]
+            [clj-time.coerce :as c]
+            [clj-time.format :as f]
             [clojure.tools.logging :as log]
             [clojure.pprint :refer [cl-format]]
             [clojure.string :refer [upper-case]]
@@ -10,75 +13,7 @@

 (defsetting slack-token "Slack API bearer token obtained from https://api.slack.com/web#authentication")

-
 (def ^:private card-width 400)
-
-(defn parse-dom
-  [stream]
-  (let [dbf (javax.xml.parsers.DocumentBuilderFactory/newInstance)]
-    (.setNamespaceAware dbf true)
-    (.setFeature dbf "http://apache.org/xml/features/nonvalidating/load-external-dtd" false)
-    (.parse (.newDocumentBuilder dbf) stream)))
-
-; ported from https://github.com/radkovo/CSSBox/blob/cssbox-4.10/src/main/java/org/fit/cssbox/demo/ImageRenderer.java
-(defn render-to-png
-  [html, os]
-  (let [is (new java.io.ByteArrayInputStream (.getBytes html java.nio.charset.StandardCharsets/UTF_8))
-        docSource (new org.fit.cssbox.io.StreamDocumentSource is nil "text/html")
-        parser (new org.fit.cssbox.io.DefaultDOMSource docSource)
-        doc (-> parser .parse)
-        windowSize (new java.awt.Dimension card-width 1)
-        media (new cz.vutbr.web.css.MediaSpec "screen")]
-    (.setDimensions media (.width windowSize) (.height windowSize))
-    (.setDeviceDimensions media (.width windowSize) (.height windowSize))
-    (let [da (new org.fit.cssbox.css.DOMAnalyzer doc (.getURL docSource))]
-      (.setMediaSpec da media)
-      (.attributesToStyles da)
-      (.addStyleSheet da nil (org.fit.cssbox.css.CSSNorm/stdStyleSheet) org.fit.cssbox.css.DOMAnalyzer$Origin/AGENT)
-      (.addStyleSheet da nil (org.fit.cssbox.css.CSSNorm/userStyleSheet) org.fit.cssbox.css.DOMAnalyzer$Origin/AGENT)
-      (.addStyleSheet da nil (org.fit.cssbox.css.CSSNorm/formsStyleSheet) org.fit.cssbox.css.DOMAnalyzer$Origin/AGENT)
-      (.getStyleSheets da)
-      (let [contentCanvas (new org.fit.cssbox.layout.BrowserCanvas (.getRoot da) da (.getURL docSource))]
-        (-> contentCanvas (.setAutoMediaUpdate false))
-        (-> contentCanvas (.setAutoSizeUpdate true))
-        (-> contentCanvas .getConfig (.setClipViewport false))
-        (-> contentCanvas .getConfig (.setLoadImages true))
-        (-> contentCanvas .getConfig (.setLoadBackgroundImages true))
-        (-> contentCanvas (.createLayout windowSize))
-        (javax.imageio.ImageIO/write (.getImage contentCanvas) "png" os)))))
-
-; ported from https://stackoverflow.com/questions/17061682/java-html-rendering-engine
-(defn render-to-png-swing
-  [html os]
-  (let [image (-> (java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment)
-              .getDefaultScreenDevice
-              .getDefaultConfiguration
-              (.createCompatibleImage card-width 600))
-        graphics (.createGraphics image)
-        jep (new javax.swing.JEditorPane "text/html" html)]
-    (.setSize jep card-width 600)
-    (.print jep graphics)
-    (javax.imageio.ImageIO/write image "png" os)))
-
-; ported from http://grepcode.com/file/repo1.maven.org/maven2/org.xhtmlrenderer/core-renderer/R8pre2/org/xhtmlrenderer/simple/Graphics2DRenderer.java
-(defn render-to-png-flying-saucer
-  [html os]
-  (let [is (new java.io.ByteArrayInputStream (.getBytes html java.nio.charset.StandardCharsets/UTF_8))
-        dom (parse-dom is)
-        renderer (new org.xhtmlrenderer.simple.Graphics2DRenderer)
-        rect (new java.awt.Dimension card-width 600)
-        buff (new java.awt.image.BufferedImage (.getWidth rect) (.getHeight rect) java.awt.image.BufferedImage/TYPE_INT_ARGB)
-        g (.getGraphics buff)]
-    (.setDocument renderer dom nil)
-    (.layout renderer g rect)
-    (.dispose g)
-    (let [rect (.getMinimumSize renderer)
-          buff (new java.awt.image.BufferedImage (.getWidth rect) (.getHeight rect) java.awt.image.BufferedImage/TYPE_INT_ARGB)
-          g (.getGraphics buff)]
-      (.render renderer g)
-      (.dispose g)
-      (javax.imageio.ImageIO/write buff "png" os))))
-

 (def ^:private font-style "font-family: Lato, \"Helvetica Neue\", Helvetica, Arial, sans-serif;")
 (def ^:private section-style font-style)
@@ -87,9 +22,26 @@
 (def ^:private bar-th-style  (str font-style "font-size: 10px; font-weight: 400; color: rgb(57,67,64); border-bottom: 4px solid rgb(248, 248, 248); padding-top: 0px; padding-bottom: 10px;"))
 (def ^:private bar-td-style  (str font-style "font-size: 16px; font-weight: 400; text-align: left; padding-right: 1em; padding-top: 8px;"))

-(defn format-number
+(defn- format-number
   [n]
   (if (integer? n) (cl-format nil "~:d" n) (cl-format nil "~,2f" n)))
+
+(defn- format-number-short
+  [n]
+  (cond
+    (>= n 1000000000) (str (cl-format nil "~,1f" (/ n 1000000000.0)) "B")
+    (>= n 1000000) (str (cl-format nil "~,1f" (/ n 1000000.0)) "M")
+    (>= n 1000) (str (cl-format nil "~,1f" (/ n 1000.0)) "K")
+    :else (str (cl-format nil "~,1f" n))))
+
+(defn- format-timestamp
+  [timestamp]
+  (let [date (c/from-long timestamp)
+        today (t/today-at 0 00)]
+    (cond
+      (t/within? (t/interval today (t/plus today (t/days 1))) date) "Today"
+      (t/within? (t/interval (t/minus today (t/days 1)) today) date) "Yesterday"
+      :else (f/unparse (f/formatter "MMM d, YYYY") date))))

 (defn render-bar-chart-row
   [index row max-value]
@@ -158,7 +110,20 @@
           ymax (apply max ys)
           yrange (- ymax ymin)
           ys' (map #(/ (- % ymin) yrange) ys)]
-      [:img {:src (generate-data-uri (render-sparkline-to-png xs' ys' 300 200) "image/png")}]))
+      [:div {:style "color: rgb(214,214,214);" }
+        [:div {:style "display: inline-block; position: relative; margin-left: 30px;" }
+          [:div {:style "position: relative;"}
+            [:div {:style "position: absolute; height: 100%; text-align: right; background-color: red;"}
+              [:div {:style "position: absolute; top: 0; right: 0;"} (format-number-short ymax)]
+              [:div {:style "position: absolute; top: 150px; right: 0;"} (format-number-short ymin)]]
+            [:img {:style "display: block; left: 20px;" :src (generate-data-uri (render-sparkline-to-png xs' ys' 285 150) "image/png")}]
+          ]
+          [:div
+            [:div {:style "height: 15px; margin-left: 10px; margin-right: 10px; border: 4px solid rgb(233,233,233); border-top: none; border-bottom: none;"} " "]
+            [:div {:style "height: 15px; margin-left: 10px; margin-right: 10px;"}
+              [:div {:style "float: left;"} (format-timestamp xmin)]
+              [:div {:style "float: right;"} (format-timestamp xmax)]]
+          ]]]))

 (defn render-pulse-card
   [card data include-title]
@@ -182,6 +147,33 @@
     [:h1 {:style (str section-style "margin: 16px; color: rgb(57,67,64);")} (:name pulse)]
     (apply vector :div (mapv render-pulse-section results))])

+; ported from https://github.com/radkovo/CSSBox/blob/cssbox-4.10/src/main/java/org/fit/cssbox/demo/ImageRenderer.java
+(defn render-to-png
+  [html, os]
+  (let [is (new java.io.ByteArrayInputStream (.getBytes html java.nio.charset.StandardCharsets/UTF_8))
+        docSource (new org.fit.cssbox.io.StreamDocumentSource is nil "text/html")
+        parser (new org.fit.cssbox.io.DefaultDOMSource docSource)
+        doc (-> parser .parse)
+        windowSize (new java.awt.Dimension card-width 1)
+        media (new cz.vutbr.web.css.MediaSpec "screen")]
+    (.setDimensions media (.width windowSize) (.height windowSize))
+    (.setDeviceDimensions media (.width windowSize) (.height windowSize))
+    (let [da (new org.fit.cssbox.css.DOMAnalyzer doc (.getURL docSource))]
+      (.setMediaSpec da media)
+      (.attributesToStyles da)
+      (.addStyleSheet da nil (org.fit.cssbox.css.CSSNorm/stdStyleSheet) org.fit.cssbox.css.DOMAnalyzer$Origin/AGENT)
+      (.addStyleSheet da nil (org.fit.cssbox.css.CSSNorm/userStyleSheet) org.fit.cssbox.css.DOMAnalyzer$Origin/AGENT)
+      (.addStyleSheet da nil (org.fit.cssbox.css.CSSNorm/formsStyleSheet) org.fit.cssbox.css.DOMAnalyzer$Origin/AGENT)
+      (.getStyleSheets da)
+      (let [contentCanvas (new org.fit.cssbox.layout.BrowserCanvas (.getRoot da) da (.getURL docSource))]
+        (-> contentCanvas (.setAutoMediaUpdate false))
+        (-> contentCanvas (.setAutoSizeUpdate true))
+        (-> contentCanvas .getConfig (.setClipViewport false))
+        (-> contentCanvas .getConfig (.setLoadImages true))
+        (-> contentCanvas .getConfig (.setLoadBackgroundImages true))
+        (-> contentCanvas (.createLayout windowSize))
+        (javax.imageio.ImageIO/write (.getImage contentCanvas) "png" os)))))
+
 (defn render-pulse-card-to-png
   [card data include-title]
   (let [html (html [:html [:body {:style "margin: 0; background-color: white;"} (render-pulse-card card data include-title)]])


testing: continued

testing: continued

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tiagoantao/turtle.git/'


Refactor: move 'header' div into component

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Reefersleep/sleepydo.git/'


Created a utility namespace for datomic functions.

error: pathspec 'src/clj/movement/util.clj' did not match any file(s) known to git

--- src/clj/movement/util.clj
+++ src/clj/movement/util.clj
@@ -0,0 +1,32 @@
+(ns movement.util
+  (:require [datomic.api :as d]
+            [clojure.java.io :as io]
+            [clojure.edn :as edn])
+  (:import datomic.Util))
+
+(def uri "datomic:pro://localhost:8000/move")
+
+(defn- read-all [f]
+  (Util/readAll (io.reader f)))
+
+(defn- transact-all [conn f]
+  (doseq [txd (read-all f)]
+    (d/transact conn txd))
+  :done)
+
+(defn- create-db []
+  (d/create-database uri))
+
+(defn- get-conn []
+  (d/connect uri))
+
+(defn- load-schema []
+  (transact-all (get-conn) (io/resource "data/schema.edn")))
+
+(defn- load-data []
+  (transact-all (get-conn) (io/resource "data/initial.edn")))
+
+(defn init-db []
+  (create-db)
+  (load-schema)
+  (load-data))