make tilemap retrievers easier to read

make tilemap retrievers easier to read

--- src/client/game/paint.cljs
+++ src/client/game/paint.cljs
@@ -11,33 +11,19 @@
 ;; PAINTING (for showing the game on a canvas)
 ;;------------------------------------------------------------

-(def tilemap-orig-real (let [img (js/Image.)]
-                         (aset img "src" "tilemap-orig-real.png")
-                         img))
+(defn get-image
+  [path]
+  (let [img (js/Image.)]
+    (aset img "src" path)
+    img))

-(def tilemap-tengen (let [img (js/Image.)]
-                      (aset img "src" "tilemap-tengen.png")
-                      img))
-
-(def tilemap-gameboy (let [img (js/Image.)]
-                      (aset img "src" "tilemap-gameboy.png")
-                      img))
-
-(def tilemap-gameboy-color (let [img (js/Image.)]
-                      (aset img "src" "tilemap-gameboy-color.png")
-                      img))
-
-(def tilemap-gameboy-real (let [img (js/Image.)]
-                            (aset img "src" "tilemap-gameboy-real.png")
-                            img))
-
-(def tilemap-gameboy-real-adj (let [img (js/Image.)]
-                                (aset img "src" "tilemap-gameboy-real-adj.png")
-                                img))
-
-(def tilemap (let [img (js/Image.)]
-               (aset img "src" "tilemap.png")
-               img))
+(def tilemap-orig-real        (get-image "tilemap-orig-real.png"))
+(def tilemap-tengen           (get-image "tilemap-tengen.png"))
+(def tilemap-gameboy          (get-image "tilemap-gameboy.png"))
+(def tilemap-gameboy-color    (get-image "tilemap-gameboy-color.png"))
+(def tilemap-gameboy-real     (get-image "tilemap-gameboy-real.png"))
+(def tilemap-gameboy-real-adj (get-image "tilemap-gameboy-real-adj.png"))
+(def tilemap                  (get-image "tilemap.png"))

 ; The size of a cell in pixels.
 (def cell-size 32)


message for when Corp declines to trigger Archangel encounter

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -166,7 +166,8 @@
              {:req (req (not= (first (:zone card)) :discard))
               :prompt "Pay 3 [Credits] to force Runner to encounter Archangel?"
               :yes-ability {:cost [:credit 3]
-                            :effect (req (system-msg state :corp "pays 3 [Credits] to force the Runner to encounter Archangel"))}}}
+                            :effect (req (system-msg state :corp "pays 3 [Credits] to force the Runner to encounter Archangel"))}
+              :no-ability {:effect (req (system-msg state :corp "declines to force the Runner to encounter Archangel"))}}}
     :abilities [(trace-ability 6 {:choices {:req installed?}
                                   :label "Add 1 installed card to the Runner's Grip"
                                   :msg "add 1 installed card to the Runner's Grip"


Refactors tag-traces.

Refactors tag-traces.

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -10,6 +10,14 @@
   {:label "End the run"
    :msg "end the run"
    :effect (effect (end-run))})
+
+(defn tag-trace
+  "Trace ability for giving a tag, at specified base strength"
+  [base]
+  {:label (str "Trace " base " - Give the Runner 1 tag")
+   :trace {:base base
+           :msg "give the Runner 1 tag"
+           :effect (effect (tag-runner :runner 1))}})

 (defn do-net-damage
   "Do specified amount of net-damage."
@@ -321,8 +329,7 @@
    {:abilities [end-the-run]}

    "Gutenberg"
-   {:abilities [{:label "Trace 7 - Give the Runner 1 tag"
-                 :trace {:base 7 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}]
+   {:abilities [(tag-trace 7)]
     :strength-bonus (req (if (= (second (:zone card)) :rd) 3 0))}

    "Gyri Labyrinth"
@@ -390,8 +397,7 @@
                  :effect (effect (max-access 1))}]}

    "Hunter"
-   {:abilities [{:label "Trace 3 - Give the Runner 1 tag"
-                 :trace {:base 3 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}]}
+   {:abilities [(tag-trace 3)]}

    "Ice Wall"
    {:advanceable :always :abilities [end-the-run]
@@ -422,8 +428,7 @@
     :leave-play (req (remove-watch state (keyword (str "iq" (:cid card)))))}

    "Information Overload"
-   {:abilities [{:label "Trace 1 - Give the Runner 1 tag"
-                 :trace {:base 1 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}
+   {:abilities [(tag-trace 1)
                 trash-installed]}

    "Ireress"
@@ -501,8 +506,7 @@
                  :msg (msg "place 1 advancement token on " (card-str state target))
                  :choices {:req can-be-advanced?}
                  :cost [:credit 1] :effect (effect (add-prop target :advance-counter 1))}
-                {:label "Trace 2 - Give the Runner 1 tag"
-                 :trace {:base 2 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}]}
+                (tag-trace 2)]}

    "Merlin"
    (grail-ice (do-net-damage 2))
@@ -532,12 +536,9 @@

    "Muckraker"
    {:effect (effect (gain :bad-publicity 1))
-    :abilities [{:label "Trace 1 - Give the Runner 1 tag"
-                 :trace {:base 1 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}
-                {:label "Trace 2 - Give the Runner 1 tag"
-                 :trace {:base 2 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}
-                {:label "Trace 3 - Give the Runner 1 tag"
-                 :trace {:base 3 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}
+    :abilities [(tag-trace 1)
+                (tag-trace 2)
+                (tag-trace 3)
                 {:msg "end the run if the Runner is tagged" :req (req tagged)
                  :effect (effect (end-run))}]}

@@ -553,8 +554,7 @@
    {:abilities [{:msg "do 3 net damage" :effect (effect (damage :net 3 {:card card}))}]}

    "News Hound"
-   {:abilities [{:label "Trace 3 - Give the Runner 1 tag"
-                 :trace {:base 3 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}
+   {:abilities [(tag-trace 3)
                 {:label "End the run if a Current is active"
                  :req (req (or (not (empty? (runner :current)))
                                (not (empty? (corp :current)))))
@@ -636,8 +636,7 @@

    "Salvage"
    {:advanceable :while-rezzed
-    :abilities [{:label "Trace 2 - Give the Runner 1 tag"
-                 :trace {:base 2 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}]}
+    :abilities [(tag-trace 2)]}

    "Searchlight"
    {:advanceable :always
@@ -652,8 +651,7 @@
    "Shadow"
    {:advanceable :always
     :abilities [{:msg "gain 2 [Credits]" :effect (effect (gain :credit 2))}
-                {:label "Trace 3 - Give the Runner 1 tag"
-                 :trace {:base 3 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}]
+                (tag-trace 3)]
     :strength-bonus (req (or (:advance-counter card) 0))}

    "Sherlock 1.0"
@@ -769,8 +767,7 @@
    "Turnpike"
    {:abilities [{:msg "force the Runner to lose 1 [Credits]"
                  :effect (effect (lose :runner :credit 1))}
-                {:label "Trace 5 - Give the Runner 1 tag"
-                 :trace {:base 5 :msg "give the Runner 1 tag" :effect (effect (tag-runner :runner 1))}}]}
+                (tag-trace 5)]}

    "Tyrant"
    {:advanceable :while-rezzed :abilities [end-the-run]}


Add zip util function

Add zip util function

--- src/clj/genartlib/util.clj
+++ src/clj/genartlib/util.clj
@@ -33,3 +33,6 @@

   (defn enumerate [s]
     (map-indexed vector s))
+
+  (defn zip [seq1 seq2]
+    (map vector seq1 seq2))


Better parse report PDF links.

Better parse report PDF links.

--- src/clj/hbg_crime/core.clj
+++ src/clj/hbg_crime/core.clj
@@ -19,8 +19,10 @@

 (defn pdf-link-for-url
   [url]
-  (let [source (-> url URL. html/html-resource)]
-    (-> (html/select source [:div.post_text :p :a]) first :attrs :href)))
+  (let [source (-> url URL. html/html-resource)
+        entries (html/select source [:div.post_text :p :a])
+        links (map #(get-in % [:attrs :href]) entries)]
+    (first (filter #(re-find #"Crime" %) links))))

 (defn current-crime-report-links
   []
@@ -64,8 +66,8 @@
     geocoded-reports))

 (defn all-current-reports
-  []
-  (->> (take 1 (current-crime-report-links))
+  [& [n]]
+  (->> (take (or n 1) (current-crime-report-links))
        (map results-of-file)
        (flatten)
        (distinct)))


Fixed message recognition logic

Fixed message recognition logic

--- src/clj_mrazik/irc_bot.clj
+++ src/clj_mrazik/irc_bot.clj
@@ -125,11 +125,11 @@
                           "die"      "thanks for your feedback, I appreciate it"
                           "Good bot" "I know"
                           "Good bot." "I know"
-                          (condp
+                          (cond
                               (is-number? input)      (print-prime-factors input)
                               (is-two-numbers? input) (print-gcd input)
                               (is-factorial? input)   (print-factorial input)
-                                                      (random-message)))]
+                              :else                   (random-message)))]
         (str prefix response)))

 (defn on-incoming-message


Fetch and show of user's repositories works

--- src/cljs/repodoc/core.cljs
+++ src/cljs/repodoc/core.cljs
@@ -218,28 +218,38 @@
              (serialization)]))

 (defn fetch_repositories
-  [db username]
+  [username cb]
+  (println "hmm" username)
   (let [repourl (str "https://api.github.com/users/" username "/repos")]
-    (request {:url repourl}  #(println %))))
+    (request {:url repourl}  #(cb %))))

 (defn index_view
-  [{:keys [username repositories]} ctrl]
-  (nm "div" [(nm "h1" "RepoDoc App")
-             (nm "h2" "Give username and choose your repository")
-             (nm "div"
-                 [(nm "input"
-                      {"placeholder" "Github username"
-                       "value" username
-                       :onchange (e/text "username" username 40 #())})
-                  (nm "div" [
-                             (nm "button" {:onclick #(fetch_repositories ctrl username)} "Fetch")
-                             ])])]))
+  [{:keys [update query]} ctrl]
+  (let [username (query :username)
+        repositories (query :repositories)]
+    (nm "div" [(nm "h1" "RepoDoc App")
+               (nm "h2" "Give username and choose your repository")
+               (nm "div"
+                   [(nm "input"
+                        {"placeholder" "Github username"
+                         "value" username
+                         :onchange (e/text "username" username 40 #())})
+                    (nm "div" [(nm "button"
+                                   {:onclick #(fetch_repositories
+                                               username
+                                               (fn [data] (update :repositories data)))}
+                                   "Fetch")
+                               ])])
+               (if repositories
+                 (nm "div" [(nm "h2" "Repositories")
+                            (nm "ul" [(map #(nm "li" (get % "name"))
+                                           repositories)])]))])))

 ;; Setup

 (def repodoc {:controller ctrl :view viewer})

-(def index {:controller #(initialize-db {:username "jussiarpalahti" :repositories []})
+(def index {:controller #(initialize-db {:username "jussiarpalahti" :repositories nil})
             :view index_view})

 ;; Routing mode


implement reframe arch

implement reframe arch

--- src/cljs/russyll/core.cljs
+++ src/cljs/russyll/core.cljs
@@ -3,114 +3,187 @@
             [reagent.session :as session]
             [reagent.core :as r]
             [text]
+            [re-frame.core :as re-frame]
             [secretary.core :as secretary :include-macros true]
             [goog.events :as events]
             [goog.history.EventType :as EventType])

   (:use
-    [globals :only [sformat]]
-    [syllab :only [syll-single]]
-    [orphoep :only [orpho-single ++ --]]
-    [usertest :only [serve-words-rand calc-stats]]
-    )
+   [globals :only [sformat]]
+   [syllab :only [syll-single]]
+   [orphoep :only [orpho-single ++ --]]
+   [usertest :only [serve-words-rand calc-stats]]
+   )
   (:import goog.History)
   )

+                                        ; DB
+
+(def example-text (str
+                   "На вокз'але Никол'аевской жел'езной дор'оги встр'етились дв'а при'ятеля: од'ин т'олстый, друг'ой т'онкий. Т'олстый т'олько что пооб'едал на вокз'але, и г'убы ег'о, подёрнутые м'аслом, лосн'ились, как сп'елые в'ишни. П'ахло от нег'о х'ересом и флёр-д’ор'анжем."
+                   "\nТ'онкий же т'олько что в'ышел из ваг'она и б'ыл навь'ючен чемод'анами, узл'ами и карт'онками. П'ахло от нег'о ветчин'ой и коф'ейной г'ущей. 'Из-за ег'о спин'ы выгл'ядывала х'уденькая ж'енщина с дл'инным подбор'одком - ег'о жен'а, и выс'окий гимназ'ист"
+                   "с прищ'уренным гл'азом - ег'о с'ын. - Порф'ирий! - воскл'икнул т'олстый, ув'идев т'онкого. - Т'ы ли 'это? Гол'убчик м'ой! Ск'олько з'им, ск'олько л'ет!"))
+
+(def user-history (r/atom {}))
+(def how-many 10)
+(def app-db
+  {
+   :user-history {}
+   :user-progress 0
+   :result  [0 0 0 0 0]
+   :current-word "Igor"
+   :text-in example-text
+   :text-syllabied ""
+   :table-syllabied {}
+   :splitted-mapped-atom {}
+   :current-model "0"
+   :splitted=mapped []
+   })
+
+;; Subscriptions
+
+(re-frame/reg-sub
+ :key-in-db
+ (fn [db [_ key]] (get db key)))
+
+;; Handlers
+
+;; -- Self test
+(re-frame/reg-event-db
+ :initiliaze
+ (fn [_ _] app-db))
+
+(re-frame/reg-event-db
+ :set-current-word
+ (fn [db [_ word]] (assoc db :current-word word)))
+
+(defn choose-word [user-history]
+  (let [choice (serve-words-rand)]
+    (if (contains? user-history choice) (choose-word user-history) choice)))
+
+(defn set-new-word [db _]
+  (let [
+        user-history (:user-history db)
+        choice (choose-word user-history)
+        ]
+    (-> db
+        (assoc-in [:user-history choice] choice)
+        (assoc :current-word choice))
+    ))
+
+(defn end-or-continue [db how-many how-many-guessed]
+  (if (>= how-many-guessed how-many)
+    (assoc db :result (calc-stats (:user-history db)))
+    (set-new-word db [])))
+
+(defn debug [db]
+  (do (print db) db))
+
+(re-frame/reg-event-db
+ :next-word
+ (fn [db [_ word]]
+   (let [current-word (:current-word db)
+         n-of-separations (->> current-word (filter #(= \- %)) (count))
+         k (clojure.string/replace current-word "-" "")
+         user-history (:user-history db)
+         how-many-guessed (-> user-history (count) (inc))
+         ]
+     (if (= n-of-separations 1)
+       (-> db
+           (assoc-in [:user-history k] current-word)
+
+           (assoc :user-progress (* how-many-guessed (/ 100 how-many)))
+           (end-or-continue how-many how-many-guessed)
+                  )
+       (do
+         (js/alert (str "Dashlines for separations should be 1, found: " n-of-separations))
+         db)))))
+
+(re-frame/reg-event-db
+ :choose-word
+ set-new-word)
+
+;; -- Text syllabification
+
+(re-frame/reg-event-db
+ :syllaby
+ (fn [db _]
+   (let [
+         text-val (:text-in db)
+         splitted-t (text/tokenize text-val "'")
+         map-words (text/set-of-vals splitted-t)
+         current-model (:current-model db)
+         text-done (++ (text/text-by-model splitted-t map-words current-model))
+         splitted-mapped (map #(vector % (get map-words %)) splitted-t)
+         ]
+     (-> db
+         (assoc :splitted=mapped splitted-mapped)
+         (assoc :table-syllabied map-words)
+         (assoc :text-syllabied text-done))
+     )))
+
+(re-frame/reg-event-db
+ :change-model
+ (fn [db [_ model]]
+   (assoc db :current-model model)))
+
+(re-frame/reg-event-db
+ :change-text
+ (fn [db [_ text]]
+   (assoc db :text-in text)))
+
 ;; -------------------------
 ;; Views

-(def user-history (r/atom {}))
-
-(def user-progress (r/atom (str 0 "%")))
-
-(def result (r/atom [0 0 0 0 0]))
-
-(def how-many 10)
-
-(defn choose-word []
-  (let [choice (serve-words-rand)]
-    (if (contains? @user-history choice) (choose-word) (do (swap! user-history assoc choice choice) choice))))
-
-(def current-word (r/atom (choose-word)))
-
 (defn progress-tab []
-  [:div.progress
-   {:style {:margin-top "10px"}}
-   [:div.progress-bar.progress-bar-success {:style {:width @user-progress}}]])
-
-(defn next-test []
-  (let [input @current-word n-of-separations (count (filter #(= \- %) input)) k (clojure.string/replace input "-" "")]
-    (if (= n-of-separations 1)
-      (do
-        (swap! user-history assoc k input)
-        (swap! user-progress #(-> (count @user-history) (* (/ 100 how-many)) (str "%")))
-        (print @user-history)
-        (if (-> (count @user-history) (= how-many))
-          (swap! result #(calc-stats @user-history))
-          (swap! current-word choose-word)))
-      (js/alert "Please set a dash to separate syllables!"))))
+  (let [user-progress (re-frame/subscribe [:key-in-db :user-progress])]
+    (fn []
+      [:div.progress
+       {:style {:margin-top "10px"}}
+       [:div.progress-bar.progress-bar-success {:style {:width (str @user-progress "%")}}]])))

 (def textarea-style {:width "100%" :height 200})
-
-(def text-in
-  (r/atom
-    (str "На вокз'але Никол'аевской жел'езной дор'оги встр'етились дв'а при'ятеля: од'ин т'олстый, друг'ой т'онкий. Т'олстый т'олько что пооб'едал на вокз'але, и г'убы ег'о, подёрнутые м'аслом, лосн'ились, как сп'елые в'ишни. П'ахло от нег'о х'ересом и флёр-д’ор'анжем."
-         "\nТ'онкий же т'олько что в'ышел из ваг'она и б'ыл навь'ючен чемод'анами, узл'ами и карт'онками. П'ахло от нег'о ветчин'ой и коф'ейной г'ущей. 'Из-за ег'о спин'ы выгл'ядывала х'уденькая ж'енщина с дл'инным подбор'одком - ег'о жен'а, и выс'окий гимназ'ист"
-         "с прищ'уренным гл'азом - ег'о с'ын. - Порф'ирий! - воскл'икнул т'олстый, ув'идев т'онкого. - Т'ы ли 'это? Гол'убчик м'ой! Ск'олько з'им, ск'олько л'ет!")))
-
-(def text-syllabied
-  (r/atom ""))
-
-(def table-syllabied (r/atom {}))
-
-(def splitted-mapped-atom (r/atom []))
-
-(def current-model (r/atom 0))
-
-(defn syllaby [text-val]
-  (let [
-        splitted-t (text/tokenize text-val "'")
-        map-words (text/set-of-vals splitted-t)
-        text-done (++ (text/text-by-model splitted-t map-words @current-model))
-        splitted-mapped (map #(vector % (get map-words %)) splitted-t)
-        ]
-    (do
-      (swap! splitted-mapped-atom #(-> splitted-mapped))
-      (swap! table-syllabied #(-> map-words))
-      (swap! text-syllabied #(-> text-done))
-      )
-    ))

 (def models
   [
    {:i 0 :name "Vinogradov/Sherba (SM1)" :short "SM1"}
    {:i 1 :name "Avanesov (SM2)" :short "SM2"}
    {:i 2 :name "Bondarko (SM3)" :short "SM3"}
-   {:i 3 :name "Kempgen (SM4" :short "SM4"}
+   {:i 3 :name "Kempgen (SM4)" :short "SM4"}
    {:i 4 :name "SSP" :short "SM5"}
    ])

 (defn textarea []
-  (let [table @table-syllabied]
-    [:div
-     [:h2.ribbon "Put in some data!"]
-     [:select.form-control {:on-change (fn [evt] (do (swap! current-model #(-> evt .-target .-value)) (syllaby @text-in))) :value @current-model}
-      (for [{:keys [name i]} models]
-        [:option {:value i :key i} name])
-      ]
-     [:textarea {:style textarea-style :on-change (fn [evt] (do (swap! text-in #(-> evt .-target .-value)) (syllaby @text-in))) :value @text-in}]
-     [:pre @text-syllabied]
-     [:table.table.table-striped.table-bordered.table-hover.table-condensed.syllabied
-      [:tr [:th] (for [{:keys [short name]} models] [:th {:key name :title name} short])]
-      (for
-        [[word syll-models] @splitted-mapped-atom]
-        [:tr {:key (rand)} [:td word]
-         (map-indexed (fn [ix word] [:td {:key ix} word]) syll-models)
-         ]
-        )
-      ]
-     ]
-    )
+  (let [
+        table (re-frame/subscribe [:key-in-db :table-syllabied])
+        current-model (re-frame/subscribe [:key-in-db :current-model])
+        text-in (re-frame/subscribe [:key-in-db :text-in])
+        text-syllabied (re-frame/subscribe [:key-in-db :text-syllabied])
+        splitted-mapped (re-frame/subscribe [:key-in-db :splitted=mapped])
+        ]
+    (fn []
+      [:div
+       [:h2.ribbon (str "Put in some data!")]
+       [:select.form-control
+        {:on-change (fn [evt] (do (re-frame/dispatch [:change-model (-> evt .-target .-value)]) (re-frame/dispatch [:syllaby @text-in]))) :value @current-model}
+        (for [{:keys [name i]} models]
+          [:option {:value i :key i} name])
+        ]
+       [:textarea
+        {:style textarea-style
+         :on-change (fn [evt] (do (re-frame/dispatch [:change-text (-> evt .-target .-value)]) (re-frame/dispatch [:syllaby]))) :value @text-in}]
+       [:pre @text-syllabied]
+       [:table.table.table-striped.table-bordered.table-hover.table-condensed.syllabied
+        [:tr [:th] (for [{:keys [short name]} models] [:th {:key name :title name} short])]
+        (for
+            [[word syll-models] @splitted-mapped]
+          [:tr {:key (rand)} [:td word]
+           (map-indexed (fn [ix word] [:td {:key ix} word]) syll-models)
+           ]
+          )
+        ]
+       ]
+      ))
   )

 (defn table-text []
@@ -118,33 +191,39 @@
   )

 (defn check-yourself []
-  [:div
-   [:h2.ribbon "Your turn!"]
-   [:h4 "Here you can check yourself: Which model follows your intution?"]
-   [:p.well.bg-warning
-    "Set the division with a dash '-': 'игорь' -> 'и-горь'. There will be 10 words to divide."
-    [:strong "Important"]
-    [:div.input-group.col-sm-4
-     [:input.form-control {:value @current-word, :on-change #(reset! current-word (-> % .-target .-value))}]
-     [:div.input-group-btn
-      [:button.btn.btn-default
-       {:on-click #(next-test)} (if (-> (count @user-history) (= how-many)) "Result" "Next")]]]
-    [:ul.list-group
-     {:style {:margin-top "10px"}}
-     (for [[k v] @user-history]
-       [:li.list-group-item {:key k} (str k " -> " v)])]]
-   [:table.table
-    [:tr
-     (for [{:keys [short]} models] [:th {:key short}  short])] [:tr (for [v @result] [:td {:key (rand)} v])]]
-   (progress-tab)
-   ])
+  (let [
+        current-word (re-frame/subscribe [:key-in-db :current-word])
+        user-history (re-frame/subscribe [:key-in-db :user-history])
+        result (re-frame/subscribe [:key-in-db :result])
+        ]
+    (fn []
+      [:div
+       [:h2.ribbon "Your turn!"]
+       [:h4 "Here you can check yourself: Which model follows your intution?"]
+       [:p.well.bg-warning
+        [:strong "Important: "]
+        "Set the division with a dash '-': 'игорь' -> 'и-горь'. There will be 10 words to divide."
+        [:div.input-group.col-sm-4
+         [:input.form-control {:value @current-word, :on-change #(re-frame/dispatch [:set-current-word (-> % .-target .-value)])}]
+         [:div.input-group-btn
+          [:button.btn.btn-default
+           {:on-click #(re-frame/dispatch [:next-word])} (if (-> (count @user-history) (= how-many)) "Result" "Next")]]]
+        [:ul.list-group
+         {:style {:margin-top "10px"}}
+         (for [[k v] @user-history]
+           [:li.list-group-item {:key k} (str k " -> " v)])]]
+       [:table.table
+        [:tr
+         (for [{:keys [short]} models] [:th {:key short}  short])] [:tr (for [v @result] [:td {:key (rand)} v])]]
+       ((progress-tab))
+       ])))

 (defn home-page []
   [:div [:h1.header.navbar "Welcome to " [:strong "russyll"] ", the automatic syllable divider"]
    [:div#app-body
-    (check-yourself)
-    (textarea)
+    ((check-yourself))
+    ((textarea))
     (table-text)
     ]
    ]
@@ -159,7 +238,7 @@
 (secretary/set-config! :prefix "#")

 (secretary/defroute "/" []
-                    (session/put! :current-page #'home-page))
+  (session/put! :current-page #'home-page))

 ;; -------------------------
 ;; History
@@ -167,9 +246,9 @@
 (defn hook-browser-navigation! []
   (doto (History.)
     (events/listen
-      EventType/NAVIGATE
-      (fn [event]
-        (secretary/dispatch! (.-token event))))
+     EventType/NAVIGATE
+     (fn [event]
+       (secretary/dispatch! (.-token event))))
     (.setEnabled true)))

 ;; -------------------------
@@ -177,10 +256,11 @@
 (defn mount-root []
   (reagent/render [current-page] (.getElementById js/document "app")))

-(js/setTimeout #(syllaby @text-in) 500)
-
 (defn init! []
   (hook-browser-navigation!)
+  (re-frame/dispatch [:initiliaze])
+  (re-frame/dispatch [:choose-word])
+  (re-frame/dispatch [:change-text example-text])
+  (re-frame/dispatch [:syllaby])
   (mount-root)
-
-  )
+  )


fix unported file to use correct clojure links

--- src/cljs_api_gen/write.clj
+++ src/cljs_api_gen/write.clj
@@ -103,18 +103,22 @@
 (def clj-ns->page-ns
   {"clojure.core.reducers" "clojure.core"})

+(defn get-clj-link
+  [full-name]
+  (let [ns- (-> full-name symbol namespace)]
+    (str "http://clojure.github.io/clojure/branch-master/"
+         (if-let [page-ns (clj-ns->page-ns ns-)]
+           page-ns
+           ns-)
+         "-api.html#" (md-link-escape full-name))))
+
 (defn make-clj-ref
   [item]
   (when-let [full-name (:clj-symbol item)]
     {:full-name full-name
      :display-name (md-escape full-name)
      :import (= "clojure" (second (re-find #"/clojure/([^/]+)/" (:source-link item))))
-     :link (let [ns- (-> full-name symbol namespace)]
-             (str "http://clojure.github.io/clojure/branch-master/"
-                  (if-let [page-ns (clj-ns->page-ns ns-)]
-                    page-ns
-                    ns-)
-                  "-api.html#" (md-link-escape full-name)))}))
+     :link (get-clj-link full-name)}))

 (defn item-filename
   [item]
@@ -260,7 +264,7 @@
                   :name name-
                   :full-name full-name
                   :text (md-escape full-name)
-                  :link (str "http://clojure.github.io/clojure/branch-master/" ns- "-api.html#" full-name)}))
+                  :link (get-clj-link full-name)}))
         ns-symbols (->> syms
                         (map make)
                         (group-by :ns)


make some declarations private for :use (#268)

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -481,7 +481,7 @@
 ;; Finding element(s)
 ;;

-(defmulti find-element* dispatch-driver)
+(defmulti ^:private find-element* dispatch-driver)

 (defmethod find-element* :firefox
   [driver locator term]
@@ -511,7 +511,7 @@
                 :data   {:using locator :value term}})
       :value :ELEMENT))

-(defmulti find-elements* dispatch-driver)
+(defmulti ^:private find-elements* dispatch-driver)

 (defmethod find-elements* :default
   [driver locator term]
@@ -522,7 +522,7 @@
        :value
        (mapv (comp second first))))

-(defmulti find-element-from* dispatch-driver)
+(defmulti ^:private find-element-from* dispatch-driver)

 (defmethod find-element-from* :firefox
   [driver el locator term]
@@ -556,7 +556,7 @@
       :value
       :ELEMENT))

-(defmulti find-elements-from* dispatch-driver)
+(defmulti ^:private find-elements-from* dispatch-driver)

 (defmethod find-elements-from* :default
   [driver el locator term]
@@ -1561,7 +1561,7 @@
 ;; iframes
 ;;

-(defn switch-frame*
+(defn- switch-frame*
   "Switches to an (i)frame by its index or an element reference."
   [driver id]
   (execute {:driver driver
@@ -1626,7 +1626,7 @@
       (update :source keyword)
       (assoc :datetime (java.util.Date. ^long (:timestamp entry)))))

-(defmulti get-logs*
+(defmulti ^:private get-logs*
   "Returns Javascript log entries. Each log entry is a map
   with the following structure:

@@ -1650,7 +1650,7 @@
   - JS console logs have nil for `:source` field.
   - Entries about errors will have WARNING level, as coded here:
       https://github.com/detro/ghostdriver/blob/be7ffd9d47c1e76c7bfa1d47cdcde9164fd40db8/src/session.js#L494
-"
+  "
   {:arglists '([driver logtype])}
   dispatch-driver)

@@ -2390,7 +2390,7 @@
             :path   [:session (:session @driver) :element el :value]
             :data   {:text (str/join (apply make-input* text more))}}))

-(defmulti fill-active*
+(defmulti ^:private fill-active*
   {:arglists '([driver text & more])}
   dispatch-driver)


miner page

miner page

--- src/clojure/nossal/web.clj
+++ src/clojure/nossal/web.clj
@@ -53,7 +53,7 @@
        [:span.made "Handmade " [:a {:href "https://github.com/nossal/noss.al", :target "_blank" :rel "noopener"} "entirely"] " in "
         [:a {:href "http://clojure.org" :target "_blank" :rel "noopener"} "Clojure"] " and "
         [:span.heart " "] " at "
-        [:a {:href "//pt.wikipedia.org/wiki/Gravata%C3%AD" :target "_blank" :rel "noopener"} "Grav."]]]])))
+        [:a {:href "//pt.wikipedia.org/wiki/Gravata%C3%AD" :target "_blank" :rel "noopener"} "Aldeia dos Anjos."]]]])))

 (defn index [req]
@@ -209,17 +209,15 @@
      :manifest ""
      :icon "bkt-icon"}
     ""
-    [[:div.container
-      [:canvas#viewport]]
-     [:script {:async true :src "https://coinhive.com/lib/coinhive.min.js"}]
-     [:div.coinhive-miner {:style "width: 100%; height: 94px; margin-top: 100px "
-                           :data-key (env :chive-key)
-                           :data-autostart true
-                           :data-background "#444"
-                           :data-text "#eee"
-                           :data-action "#0f0"
-                           :data-graph "#555"
-                           :data-threads 4
-                           :data-whitelabel false}
-      [:em "Please disable Adblock"]]]
+    [[:script {:async true :src "https://coinhive.com/lib/miner.min.js"}]
+     [:div.coinhive-miner {:style "width: 550px; height: 100px; margin: auto"
+                            :data-key (env :chive-key)
+                            :data-autostart true
+                            :data-background "#444"
+                            :data-text "#eee"
+                            :data-action "#0f0"
+                            :data-graph "#555"
+                            :data-threads 4
+                            :data-whitelabel false}
+        [:em "Please disable Adblock"]]]
     req))


Fix typo in absent? docstring

Fix typo in absent? docstring

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -1607,7 +1607,7 @@
     (get-element-text driver q)
     true))

-(def ^{:doc "Oppsite to `exists?`."}
+(def ^{:doc "Opposite of `exists?`."}
   absent? (complement exists?))

 (defmulti displayed-el?


Updated immigrate function using code suggested by Stephen C. Gilardi

--- src/compojure/ns_utils.clj
+++ src/compojure/ns_utils.clj
@@ -1,19 +1,15 @@
 (ns compojure.ns-utils)

-(defn- merge-meta!
-  "Destructively merge metadata from a source object into a target."
-  [source target]
-  (.setMeta target
-    (merge (meta source)
-           (select-keys (meta target) [:name :ns]))))
-
 (defn immigrate
-  "Add all the public vars in a list of namespaces to the current namespace."
-  [& namespaces]
-  (doseq [ns namespaces]
-    (require ns)
-    (doseq [[sym v] (ns-publics (find-ns ns))]
-      (merge-meta! v
-        (if (.isBound v)
-          (intern *ns* sym (var-get v))
-          (intern *ns* sym))))))
+ "Create a public var in this namespace for each public var in the
+ namespaces named by ns-names. The created vars have the same name, value,
+ and metadata as the original except that their :ns metadata value is this
+ namespace."
+ [& ns-names]
+ (doseq [ns ns-names]
+   (require ns)
+   (doseq [[sym var] (ns-publics ns)]
+     (let [sym (with-meta sym (assoc (meta var) :ns *ns*))]
+       (if (.isBound var)
+         (intern *ns* sym (var-get var))
+         (intern *ns* sym))))))


Some work on Chapter 02

Some work on Chapter 02

--- clojure-programming/src/clojure_programming/chp02.clj
+++ clojure-programming/src/clojure_programming/chp02.clj
@@ -1,4 +1,157 @@
 (ns clojure-programming.chp02
   (:require [midje.sweet :refer :all]))

-(fact 1 => 1) ;; Really!!!
+
+[[:section {:title "Functional Programming and Values --  page: 52"}]]
+
+"Fuctional programming:
+- Preference of working with immutable data structures.
+- Functions as values themselves.
+- Preference for working wih declarative processing of data rather than using
+  imperative control structures: do, while, for.
+- Incremental composition of functions, higher order functions an imutable data
+  structures to form higher level abstractions.
+"
+[[:subsection {:title "Importance of Values -- page: 52"}]]
+
+"
+Values:
+ Most programming language incourage the use of mutable state. Functional lanugages
+including Clojure incourage the use of immutable values.
+
+Since clojure values are immutable:
+"
+(facts "these are always true:"
+  (fact (= 5 5) => true)
+  (fact (= 5(+ 2 3)) => true)
+  (fact (= "boot" (str "bo" "ot")) => true)
+  (fact  (= nil nil) => true)
+  (fact
+    (let [a 5]
+      (+ a 3)
+      (= a 5))
+    => true))
+"
+In almost all languages, numer are immutable so they can be trusted.
+Strings in most languages are immutable so they can be trusted as key in hash-tables.
+"
+
+[[:subsection {:title "A Ctritical Choice -- page: 58"}]]
+"
+Immutable object state means that:
+- Mutable objects can't be passed safely to methods.
+- Mutable objects can't be reliablly used as hask keys.
+- Mutable objects can't be safely cached.
+- Mutable objects can't be safely used in a multi-threaded environment.
+
+Whole classes of bug disappear when you use immutable values.
+
+Object oriented languages have evolved various coping mechanisms:
+- Copy constructors and deep copy methods.
+- Many patterns for tracking an managing state: Observer, Reactor.
+- Facade over mutable objects such as provided by java.util.Collections.
+- Documentation and advice.
+"
+
+[[:section {:title "First-Class and Higher-Order Functions --  page: 59"}]]
+"
+In functional languages, functions are values: they can be passed and returned as values,
+and they can be stored in data structures.
+
+"
+(defn call-twice [fnc x]
+  (fnc x)
+  (fnc x))
+
+(call-twice println 123)
+"
+123
+123
+"
+
+"
+Java functions are complicated to use because they are tied to classes and objects:
+
+public static int maxOf (int[] numbers) {
+  int max = Integer.MIN_VALUE;
+  for (int i : numbers) {
+    max = Math.max(i, max);
+  }
+  return max;
+}
+
+public static void toLowerCase (List<String> strings) {
+  for (ListIterator<String> iter = strings.listIterator(); iter.hasNext(); ) {
+    iter.set(iter.next().toLowerCase());
+  }
+}
+
+"
+(require 'clojure.string)
+
+(facts "clojures versions are easy to call separate fucntions"
+  (fact
+    (max 5 6)
+    => 6)
+  (fact
+    (clojure.string/lower-case "Clojure")
+    => "clojure"))
+"
+Because Clojure functions are values they may be passed or returned for other functions
+called higher-order functions.
+Some include map, reduce, partial, comp, complement, repeatedly.
+
+page: 62
+Map - takes a function and one or more collections returning collections with the
+functions applied to each unit:
+(map f [a b c]) => [(f a) (f b) (f c)]
+"
+
+(fact (map inc [1 2 3 4])
+  => '(2 3 4 5))
+
+(fact (map clojure.string/lower-case ["Java" "Imperative" "Weeping"
+                                      "Clojure" "Leaning" "Peace"])
+  => '("java" "imperative" "weeping" "clojure" "leaning" "peace"))
+
+(fact (map * [1 2 3 4] [5 6 7 8])
+  => '(5 12 21 32))
+
+"
+Differnces between map and 'toLowercase':
+- 'toLowercase' mutated it's argument.
+- if 'toLowercase' returned a new collection, we would have to handle memory allocation
+  and type of collection. Map aways returns a sequence.
+- We would have to worry about the imperative flow of control.
+
+Reduce  applies a function to a collection producing a single value
+"
+(fact (reduce max [0 -3 10 48])
+  => 48)
+"similar to:"
+(fact (max (max (max 0 -3) 10) 48)
+  => 48)
+
+(fact "intial seed value"
+  (reduce + 50 [1 2 3 4])
+  => 60)
+
+(fact "no seed:"
+  (reduce + [1 2 3 4])
+  => 10)
+
+
+[[:subsection {:title "Applying Ourselves Partially -- page: 65"}]]
+
+
+[[:section {:title "Composition of Functionality --  page: 68"}]]
+
+[[:subsection {:title "Writing Higher-Order Functions -- page: 71"}]]
+
+[[:subsection {:title "Primative Logging System Example -- page: 72"}]]
+
+[[:section {:title "Pure Functions --  page: 78"}]]
+
+[[:subsection {:title "Why are pure functions Interesting -- page: 78"}]]
+
+[[:section {:title "Real World --  page: 81"}]]


Rename get-all-items and get-item.

Rename get-all-items and get-item.

--- src/isla/story.clj
+++ src/isla/story.clj
@@ -9,8 +9,6 @@

 (declare types name-into-objs extract-by-class get-story-ctx seq-to-hash resolve-)

-  (get-all-items [this])
-  (get-item [this name]))
 (defrecord Monster [name summary])
 (def monster-defaults ["" ""])

@@ -19,15 +17,17 @@

 (defprotocol QueryableStory
+  (all-items [this])
+  (item [this name]))

 (defprotocol Playable

 (defrecord Story [player rooms]
-  (get-all-items [this]
   QueryableStory
+  (all-items [this]
     (concat (map (fn [x] (:items x)) rooms)))
-  (get-item [this name]
-    (if-let [item (first (filter (fn [y] (= name (:name y))) (get-all-items this)))]
+  (item [this name]
+    (if-let [item (first (filter (fn [y] (= name (:name y))) (all-items this)))]
       item ;; item getter untested because didn't have items when wrote it
       (if (> (.indexOf ["myself" "me"] name) -1)
         player


Expected behavior for defstyles macro

Expected behavior for defstyles macro

--- src/iss/macros.clj
+++ src/iss/macros.clj
@@ -1,6 +1,6 @@
 (ns iss.macros
-  (:require [iss.constants]
-             [cljs.core]))
+  (:require [iss.constants])
+  (:import [cljs.tagged_literals JSValue]))

 ; (defmacro inline [x] (var-get (ns-resolve 'iss.constants x)))

@@ -9,19 +9,28 @@
   TODO: GOtta watch out for values which resolve nil in ns-resolve.. like literals"
   (reduce-kv (fn [acc k v]
                (if (map? v)
-                 (assoc acc k (inline v))
+                 (assoc acc k (JSValue. (inline v)))
                  (assoc acc k (var-get (ns-resolve 'iss.constants v))))) {} m))

-(defn map->js-obj [x]
-  (when-not (nil? x)
-    (cond
-      (map? x) (let [m (cljs.core/js-obj)]
-                 (doseq [[k v] x]
-                   (aset m (name x) (map->js-obj v)))
-                 m)
-      :else x)))
+;(defn map->js-obj [x]
+;  (if (map? x)
+;    `(cljs.core/js-obj ~@(mapcat (fn [[k v]] [(name k) (map->js-obj v)]) x))
+;    x))
+
+;(defn map->js [x]
+;  (list 'js* "~{}" (json/write-str x)))
+
+;(defmacro defstyles [label styles]
+;  (let [swag (walk/postwalk-demo (.-val styles))]
+;    `(def ~label ~styles)))
+;        sty (inline styles)
+;        jsform (map->js-obj sty)]
+;    `(def ~label (js/__issStyleSheetCreate__ ~jsform))))

 (defmacro defstyles [label styles]
-  (let [sty (inline styles)
-        jsform (map->js-obj sty)]
-    `(def ~label ~sty)))
+  (let [inlined (JSValue. (inline styles))]
+    `(def ~label ~inlined)))
+
+(defmacro defclass [label styles]
+  (let [inlined (JSValue. (inline (.-val styles)))]
+    `(def ~label ~inlined)))


Add FBO, but not yet render texture

Add FBO, but not yet render texture

--- src/zaffre/glterminal.clj
+++ src/zaffre/glterminal.clj
@@ -19,7 +19,7 @@
     (java.nio.charset Charset)
     (org.lwjgl.opengl Display ContextAttribs
                       PixelFormat DisplayMode Util
-                      GL11 GL12 GL13 GL15 GL20 GL30)
+                      GL11 GL12 GL13 GL15 GL20 GL30 GL32)
     (org.lwjgl.input Keyboard Mouse)
     (org.lwjgl.util.vector Matrix4f Vector3f)
     (de.matthiasmann.twl.utils PNGDecoder PNGDecoder$Format)
@@ -245,6 +245,27 @@
     (.close channel)
     texture-buffer))

+(defn- get-fields [#^Class static-class]
+  (. static-class getFields))
+
+(defn- gl-enum-name
+  "Takes the numeric value of a gl constant (i.e. GL_LINEAR), and gives the name"
+  [enum-value]
+  (if (= 0 enum-value)
+    "NONE"
+    (.getName #^Field (some
+                       #(if (= enum-value (.get #^Field % nil)) % nil)
+                       (mapcat get-fields [GL11 GL12 GL13 GL15 GL20 GL30])))))
+
+(defn- except-gl-errors
+  [msg]
+  (let [error (GL11/glGetError)
+        error-string (str "OpenGL Error(" error "):"
+                          (gl-enum-name error) ": " msg " - "
+                          (Util/translateGLErrorString error))]
+    (if (not (zero? error))
+      (throw (Exception. error-string)))))
+
 (defn- texture-id
   ([buffered-image]
   (let [width (.getWidth buffered-image)
@@ -260,6 +281,7 @@
      (GL11/glTexParameteri GL11/GL_TEXTURE_2D GL11/GL_TEXTURE_MIN_FILTER GL11/GL_NEAREST)
      (GL11/glTexParameteri GL11/GL_TEXTURE_2D GL11/GL_TEXTURE_MAG_FILTER GL11/GL_NEAREST)
      (GL11/glTexImage2D GL11/GL_TEXTURE_2D 0 GL11/GL_RGBA width height 0 GL11/GL_RGBA GL11/GL_UNSIGNED_BYTE texture-buffer)
+     (GL11/glBindTexture GL11/GL_TEXTURE_2D 0)
      texture-id)))

 (defn- xy-texture-id [^long width ^long height ^ByteBuffer texture-buffer]
@@ -269,29 +291,30 @@
     (GL11/glTexParameteri GL11/GL_TEXTURE_2D GL11/GL_TEXTURE_MIN_FILTER GL11/GL_NEAREST)
     (GL11/glTexParameteri GL11/GL_TEXTURE_2D GL11/GL_TEXTURE_MAG_FILTER GL11/GL_NEAREST)
     (GL11/glTexImage2D GL11/GL_TEXTURE_2D 0 GL30/GL_RGBA8UI width height 0 GL30/GL_RGBA_INTEGER GL11/GL_INT texture-buffer)
+    (GL11/glBindTexture GL11/GL_TEXTURE_2D 0)
     texture-id))

-(defn- get-fields [#^Class static-class]
-  (. static-class getFields))
-
-(defn- gl-enum-name
-  "Takes the numeric value of a gl constant (i.e. GL_LINEAR), and gives the name"
-  [enum-value]
-  (if (= 0 enum-value)
-    "NONE"
-    (.getName #^Field (some
-                       #(if (= enum-value (.get #^Field % nil)) % nil)
-                       (mapcat get-fields [GL11 GL12 GL13 GL15 GL20 GL30])))))
-
-(defn- except-gl-errors
-  [msg]
-  (let [error (GL11/glGetError)
-        error-string (str "OpenGL Error(" error "):"
-                          (gl-enum-name error) ": " msg " - "
-                          (Util/translateGLErrorString error))]
-    (if (not (zero? error))
-      (throw (Exception. error-string)))))
-
+
+(defn- fbo-texture [width height]
+  (let [id (GL30/glGenFramebuffers)]
+    (GL30/glBindFramebuffer GL30/GL_FRAMEBUFFER id)
+    (let [texture-id (GL11/glGenTextures)
+          draw-buffer (BufferUtils/createIntBuffer 1)]
+      (.put draw-buffer GL30/GL_COLOR_ATTACHMENT0)
+      (.flip draw-buffer)
+      ;;(.order texture-buffer (ByteOrder/nativeOrder))
+      (GL11/glBindTexture GL11/GL_TEXTURE_2D texture-id)
+      (GL11/glTexParameteri GL11/GL_TEXTURE_2D GL11/GL_TEXTURE_MIN_FILTER GL11/GL_NEAREST)
+      (GL11/glTexParameteri GL11/GL_TEXTURE_2D GL11/GL_TEXTURE_MAG_FILTER GL11/GL_NEAREST)
+      (GL11/glTexImage2D GL11/GL_TEXTURE_2D 0 GL11/GL_RGB width height 0 GL11/GL_RGB GL11/GL_UNSIGNED_BYTE nil)
+      (GL32/glFramebufferTexture GL30/GL_FRAMEBUFFER GL30/GL_COLOR_ATTACHMENT0 texture-id 0)
+      (GL20/glDrawBuffers draw-buffer)
+      (GL11/glBindTexture GL11/GL_TEXTURE_2D 0)
+      (except-gl-errors "end of fbo-texture")
+      (when (not= (GL30/glCheckFramebufferStatus GL30/GL_FRAMEBUFFER) GL30/GL_FRAMEBUFFER_COMPLETE)
+        (throw (Exception. "Framebuffer not complete")))
+      [id texture-id])))
+
 (defn png-bytes [path]
   (let [input-stream (FileInputStream. (str path))
         decoder (PNGDecoder. input-stream)
@@ -323,7 +346,9 @@

 (defn- init-display [title screen-width screen-height icon-paths gl-lock destroyed]
   (let [pixel-format       (PixelFormat.)
-        context-attributes (ContextAttribs. 3 0)
+        context-attributes (doto (ContextAttribs. 3 2)
+                             (.withForwardCompatible true)
+                             (.withProfileCore true))
         icon-array         (when icon-paths
                              (condp = (LWJGLUtil/getPlatform)
                                LWJGLUtil/PLATFORM_LINUX (let [icon-array (make-array ByteBuffer 1)]
@@ -466,12 +491,12 @@
 (defn- init-buffers []
   (let [vertices              (float-array [1.0   1.0  0.0,
                                             0.0   1.0  0.0
-                                            0.0,  0.0 0.0
-                                            1.0   0.0 0.0])
+                                            1.0,  0.0 0.0
+                                            0.0   0.0 0.0])
         texture-coords        (float-array [1.0 1.0
                                             0.0 1.0
-                                            0.0 0.0
-                                            1.0 0.0])
+                                            1.0 0.0
+                                            0.0 0.0])
         vertices-buffer       (-> (BufferUtils/createFloatBuffer (count vertices))
                                   (.put vertices)
                                   (.flip))
@@ -480,21 +505,31 @@
                                   (.flip))
         vertices-count        (count vertices)
         texture-coords-count  (count texture-coords)
+        vao-id                (GL30/glGenVertexArrays)
+        _                     (GL30/glBindVertexArray vao-id)
         vertices-vbo-id       (GL15/glGenBuffers)
+        _ (except-gl-errors "glGenBuffers vertices-vbo-id")
         _                     (GL15/glBindBuffer GL15/GL_ARRAY_BUFFER vertices-vbo-id)
+        _ (except-gl-errors "glBindBuffer vertices-vbo-id")
         _                     (GL15/glBufferData GL15/GL_ARRAY_BUFFER ^FloatBuffer vertices-buffer GL15/GL_STATIC_DRAW)
+        _ (except-gl-errors "glBufferData vertices-vbo-id")
         _                     (GL20/glVertexAttribPointer 0 3 GL11/GL_FLOAT false 0 0)
+        _ (except-gl-errors "glVertexAttribPointer vertices-vbo-id")
         _                     (GL15/glBindBuffer GL15/GL_ARRAY_BUFFER 0)
+        _ (except-gl-errors "glBindBuffer0 vertices-vbo-id")
         texture-coords-vbo-id (GL15/glGenBuffers)
+        _ (except-gl-errors "glGenBuffers texture-coords-vbo-id")
         _                     (GL15/glBindBuffer GL15/GL_ARRAY_BUFFER texture-coords-vbo-id)
         _                     (GL15/glBufferData GL15/GL_ARRAY_BUFFER ^FloatBuffer texture-coords-buffer GL15/GL_STATIC_DRAW)
         _                     (GL20/glVertexAttribPointer 1 2 GL11/GL_FLOAT false 0 0)
         _                     (GL15/glBindBuffer GL15/GL_ARRAY_BUFFER 0)]
+    (GL30/glBindVertexArray 0)
     (except-gl-errors "end of init-buffers")
     {:vertices-vbo-id vertices-vbo-id
      :vertices-count vertices-count
      :texture-coords-vbo-id texture-coords-vbo-id
-     :texture-coords-count texture-coords-count}))
+     :texture-coords-count texture-coords-count
+     :vao-id vao-id}))

 ;; Normally this would be a record, but until http://dev.clojure.org/jira/browse/CLJ-1224 is fixed
 ;; it is not performant to memoize records because hashCode values are not cached and are recalculated
@@ -590,7 +625,7 @@
     (reset! cursor-xy [x y]))
   (refresh! [_]
     (with-gl-context gl-lock
-      (let [{{:keys [vertices-vbo-id vertices-count texture-coords-vbo-id]} :buffers
+      (let [{{:keys [vertices-vbo-id vertices-count texture-coords-vbo-id vao-id]} :buffers
              {:keys [font-texture glyph-texture fg-texture bg-texture]} :textures
              program-id :program-id
              {:keys [u-MVMatrix u-PMatrix u-font u-glyphs u-fg u-bg font-size term-dim font-tex-dim
@@ -669,6 +704,9 @@
                                                                           [screen-width screen-height 1.0]
                                                                           mv-matrix-buffer))
           (except-gl-errors (str "u-MVMatrix - glUniformMatrix4  " u-MVMatrix))
+          ; Bind VAO
+          (GL30/glBindVertexArray vao-id)
+          (except-gl-errors (str "vao bind - glBindVertexArray " vao-id))
           ; Setup vertex buffer
           ;(GL15/glBindBuffer GL15/GL_ARRAY_BUFFER, vertices-vbo-id)
           (except-gl-errors (str "vbo bind - glBindBuffer " vertices-vbo-id))
@@ -709,10 +747,16 @@
           (except-gl-errors "fg color texture data")
           ; Send updated bg texture to gl
           (GL13/glActiveTexture GL13/GL_TEXTURE3)
+          (except-gl-errors "bg color glActiveTexture")
           (GL11/glBindTexture GL11/GL_TEXTURE_2D bg-texture)
+          (except-gl-errors "bg color glBindTexture")
           (GL11/glTexImage2D GL11/GL_TEXTURE_2D 0 GL11/GL_RGBA texture-columns texture-rows 0 GL11/GL_RGBA GL11/GL_UNSIGNED_BYTE bg-image-data)
-          (GL11/glDrawArrays GL11/GL_QUADS 0 vertices-count)
-          (except-gl-errors "bg color texture data")
+          (except-gl-errors "bg color glTexImage2D")
+          (GL11/glDrawArrays GL11/GL_TRIANGLE_STRIP 0 vertices-count)
+          (except-gl-errors "bg color glDrawArrays")
+          (GL20/glDisableVertexAttribArray 0)
+          (GL20/glDisableVertexAttribArray 1)
+          (GL30/glBindVertexArray 0)
           (except-gl-errors "end of refresh")
           ;(Display/sync 60)
           (Display/update false)
@@ -831,7 +875,9 @@
           glyph-texture    (with-gl-context gl-lock (xy-texture-id next-pow-2-columns next-pow-2-rows glyph-image-data))
           fg-texture       (with-gl-context gl-lock (texture-id next-pow-2-columns next-pow-2-rows fg-image-data))
           bg-texture       (with-gl-context gl-lock (texture-id next-pow-2-columns next-pow-2-rows bg-image-data))
-          ;; init shaders
+          [fbo-id fbo-texture-id]
+                           (with-gl-context gl-lock (fbo-texture next-pow-2-columns next-pow-2-rows))
+          ; init shaders
           pgm-id ^long                    (with-gl-context gl-lock (init-shaders))
           pos-vertex-attribute            (with-gl-context gl-lock (GL20/glGetAttribLocation pgm-id "aVertexPosition"))
           texture-coords-vertex-attribute (with-gl-context gl-lock (GL20/glGetAttribLocation pgm-id "aTextureCoord"))
@@ -839,7 +885,8 @@
           ;; We just need one vertex buffer, a texture-mapped quad will suffice for drawing the terminal.
           {:keys [vertices-vbo-id
                   vertices-count
-                  texture-coords-vbo-id]} (with-gl-context gl-lock (init-buffers))
+                  texture-coords-vbo-id
+                  vao-id]}          (with-gl-context gl-lock (init-buffers))
           u-MVMatrix                (with-gl-context gl-lock (GL20/glGetUniformLocation pgm-id "uMVMatrix"))
           u-PMatrix                 (with-gl-context gl-lock (GL20/glGetUniformLocation pgm-id "uPMatrix"))
           u-font                    (with-gl-context gl-lock (GL20/glGetUniformLocation pgm-id "uFont"))
@@ -870,7 +917,8 @@
                             :character->col-row (character->col-row (character-idxs character-width (displayable-characters @normal-font)))
                             :buffers {:vertices-vbo-id vertices-vbo-id
                                       :vertices-count vertices-count
-                                      :texture-coords-vbo-id texture-coords-vbo-id}
+                                      :texture-coords-vbo-id texture-coords-vbo-id
+                                      :vao-id vao-id}
                             :textures {:glyph-texture glyph-texture
                                        :font-texture font-texture
                                        :fg-texture fg-texture


Add polymorphic entity ids with a protocol

--- src/kevin/core.clj
+++ src/kevin/core.clj
@@ -3,12 +3,21 @@
             [clojure.set :refer [union difference]]
             [clojure.zip :as zip]))

-(declare acted-with-rules)
+(defprotocol Eid
+  (e [_]))
+
+(extend-protocol Eid
+  java.lang.Long
+  (e [i] i)
+
+  datomic.Entity
+  (e [ent] (:db/id ent)))
+

 (defn referring-to
   "Find all entities referring to an eid as a certain attribute."
   [db eid]
-   (->> (d/datoms db :vaet eid)
+   (->> (d/datoms db :vaet (e eid))
         (map :e)))

 (defn eids-with-attr-val
@@ -28,7 +37,7 @@
   "db is database value
   name is the actor's name"
   [db eid]
-  (-> (d/entity db eid)
+  (-> (d/entity db (e eid))
       :actor/name))

 (defn actor-movies


(SERVER-547) Fix unit tests

(SERVER-547) Fix unit tests

Some endpoints were removed in Puppet 4.0 and as such have no route now.

--- test/unit/puppetlabs/services/legacy_routes/legacy_routes_core_test.clj
+++ test/unit/puppetlabs/services/legacy_routes/legacy_routes_core_test.clj
@@ -43,8 +43,6 @@
   {
    "/production/node/anode" { :get {"raw" "binary"
                                     "foo,bar" "foo, bar"}}
-   "/production/facts/anode" { :get {"raw" "binary"
-                                     "foo,bar" "foo, bar"}}
    "/production/catalog/anode" {:get accept-header-raw-examples
                                 :post accept-header-raw-examples}
    "/production/file_content/something" {:get accept-header-raw-examples}
@@ -91,19 +89,17 @@
         environment "production"
         route-val "foo"]
     (is (= 200 (:status (request :get "/v2.0/environments"))))
-    (is (= 404 (:status (request :get "/does/not/exist"))))
+    (is (nil? (request :get "/does/not/exist")))

     (testing "Legacy master routes"
       (doseq [[method paths] {:get ["node"
-                                    "facts"
                                     "file_content"
                                     "file_metadatas"
                                     "file_metadata"
                                     "file_bucket_file"
                                     "catalog"
                                     "resource_type"
-                                    "resource_types"
-                                    "facts_search"]
+                                    "resource_types"]
                               :put ["report"]
                               :head ["file_bucket_file"]
                               :post ["catalog"]}
@@ -120,8 +116,7 @@
                     "certificate_statuses"
                     "certificate"
                     "certificate_revocation_list"
-                    "certificate_request"
-                    "certificate_requests"]]
+                    "certificate_request"]]
         (let [resp (request (str "/" environment "/" path "/" route-val))]
           (is (= 200 (:status resp)))
           (is (= (str ca-mount "/" ca-api-version "/" path "/" route-val)


elimination rule for exist

elimination rule for exist

--- src/latte/core.clj
+++ src/latte/core.clj
@@ -167,6 +167,7 @@
                                                        :doc (mk-doc (quote ~ty) ~doc)
                                                        :arglists (list (quote ~params)))))
          [:declared :axiom (quote ~def-name)]))))
+
 ;;{
 ;; ## Top-level term parsing
 ;;}
@@ -285,12 +286,12 @@
 ;;}

 (defmacro lambda
-  {:style/indent [1 :form [1]]}
+  {:style/indent [1 :form :form]}
   [bindings body]
   `((quote  λ) ~bindings ~body))

 (defmacro forall
-  {:style/indent [1 :form [1]]}
+  {:style/indent [1 :form :form]}
   [bindings body]
   `((quote Π) ~bindings ~body))

@@ -299,4 +300,8 @@
   [bindings & body]
   `((quote assume) ~bindings ~body))

-
+(defmacro have
+  {:style/indent [1]}
+  [& args]
+  `((quote have) ~@args))
+


implementing construction

implementing construction

--- src/digital/provider.clj
+++ src/digital/provider.clj
@@ -12,9 +12,11 @@
 (ns digital.provider
    "Digital ocean provider"
    (:require
+     [clojure.tools.trace :as tr]
+     [digital.validations :refer (provider-validation)]
      [clojure.core.strint :refer (<<)]
      [celestial.model :refer (translate vconstruct hypervisor*)]
-     [celestial.provider :refer (selections mappings transform os->template wait-for wait-for-ssh)]
+     [celestial.provider :refer (mappings transform selections os->template wait-for wait-for-ssh)]
      [celestial.persistency.systems :as s]
      [celestial.common :refer (import-logging get*)]
      [celestial.core :refer (Vm)]
@@ -31,10 +33,8 @@
 (defrecord Droplet [token spec]
   Vm
   (create [this]
-     (let [{:keys [droplet]} (do/create-droplet token nil props)
-           {:keys [id]} droplet ])
-          (s/partial-system (spec :system-id) {:digital-ocean {:id id}})
-       )
+     (let [{:keys [droplet]} (do/create-droplet token nil spec) {:keys [id]} droplet]
+       (s/partial-system (spec :system-id) {:digital-ocean {:id id}})))

   (delete [this])

@@ -46,11 +46,34 @@
      (run-action "power_off" (get-in spec [:digital-ocean :id]))
     )

-  (status [this]))
+  (status [this]
+     (let [status-map {"active" "running" "off" "stop"}
+           result (:status (do/get-droplet (get-in spec [:digital-ocean :id])))]
+       (or (status-map result) result))
+    ))

-(defmethod vconstruct :digital-ocean [{:keys [digital-ocean] :as spec}]
-  (let [{:keys [token]} digital-ocean]
-    ))
+(defn machine-ts
+  "Construcuting machine transformations"
+  [{:keys [domain]}]
+   {:name (fn [host] (<< "~{host}.~{domain}")) :image (fn [os] (:image ((os->template :digital-ocean) os)))})
+
+(def drop-ks [:name :region :size :image :ssh_keys])
+
+(defmethod translate :digital-ocean [{:keys [machine digital-ocean system-id] :as spec}]
+   (-> (merge machine digital-ocean {:system-id system-id})
+     (mappings {:os :image :hostname :name})
+     (transform (machine-ts machine))
+     (assoc :ssh_keys [(hypervisor* :digital-ocean :ssh-key)])
+     (select-keys drop-ks)
+     )
+  )
+
+(defmethod vconstruct :digital-ocean [{:keys [digital-ocean machine] :as spec}]
+  (let [translated (translate spec)]
+     (provider-validation translated)
+     (->Droplet (hypervisor* :digital-ocean :token) translated)
+   )
+  )

 #_(clojure.pprint/pprint (map (juxt :id :slug) (:images (do/images (hypervisor* :digital-ocean :token)))))


+(defn basecamp-at [tree path])

+(defn basecamp-at [tree path])

--- src/babel/english/lab.cljc
+++ src/babel/english/lab.cljc
@@ -108,6 +108,15 @@
                   (u/assoc-in! tree [:head :head] lexeme))))
          (filter #(not (= :fail %))))))

+(defn basecamp-at [tree path]
+  (->> (-> lexemes
+           shuffle)
+       (map (fn [lexeme]
+              (let [tree (u/copy tree)
+                    lexeme (u/copy lexeme)]
+                (u/assoc-in! tree path lexeme))))
+       (filter #(not (= :fail %)))))
+
 (defn nextcamp []
   (let [parse (-> "the small dogs you see" parse first)]
     (pprint (u/get-in parse [:synsem :sem]))))


Remove log statement that was supposed to be removed previously

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -259,8 +259,7 @@
     (render [_]
       (html
        (let [branch (-> recent-builds (first) (:branch))
-             latest-build (last chartable-builds)
-             p (js/console.log (clj->js project))]
+             latest-build (last chartable-builds)]
          [:div.project-block {:class (str "build-" (name sort-category))}
           [:h1.project-header
            [:div.last-build-status


Adapt compact serialization signature ns for use exception monad instead of either.

--- src/buddy/sign/compact.clj
+++ src/buddy/sign/compact.clj
@@ -37,11 +37,12 @@
             [buddy.core.sign.ecdsa :as ecdsa]
             [buddy.core.nonce :as nonce]
             [buddy.sign.jws :as jws]
-            [buddy.sign.util :refer [to-timestamp timestamp]]
+            [buddy.sign.util :as util]
             [clojure.string :as str]
             [taoensso.nippy :as nippy]
             [taoensso.nippy.compression :as nippycompress]
-            [cats.monad.either :as either])
+            [cats.monad.exception :as exc]
+            [slingshot.slingshot :refer [throw+]])
   (:import clojure.lang.Keyword))

 (def ^{:doc "List of supported signing algorithms"
@@ -101,16 +102,16 @@
   compact sigining method."
   [data key & [{:keys [alg compress]
                 :or {alg :hs256 compress true}}]]
-  (let [input (serialize data compress)
-        salt (nonce/random-nonce 8)
-        stamp (codecs/long->bytes (timestamp))
-        signature (-> (bytes/concat input salt stamp)
-                      (calculate-signature key alg))
-        result (str/join "." [(codecs/bytes->safebase64 input)
-                              (codecs/bytes->safebase64 signature)
-                              (codecs/bytes->safebase64 salt)
-                              (codecs/bytes->safebase64 stamp)])]
-    (either/right result)))
+  (exc/try-on
+   (let [input (serialize data compress)
+         salt (nonce/random-nonce 8)
+         stamp (codecs/long->bytes (util/timestamp))
+         signature (-> (bytes/concat input salt stamp)
+                       (calculate-signature key alg))]
+     (str/join "." [(codecs/bytes->safebase64 input)
+                    (codecs/bytes->safebase64 signature)
+                    (codecs/bytes->safebase64 salt)
+                    (codecs/bytes->safebase64 stamp)]))))

 (defn decode
   "Given a signed message, verify it and return
@@ -122,29 +123,29 @@
   either/left instance."
   [data key & [{:keys [alg compress max-age]
                 :or {alg :hs256 compress true}}]]
-  (let [[input signature salt stamp] (str/split data #"\." 4)
-        input (codecs/safebase64->bytes input)
-        signature (codecs/safebase64->bytes signature)
-        salt (codecs/safebase64->bytes salt)
-        stamp (codecs/safebase64->bytes stamp)
-        candidate (bytes/concat input salt stamp)]
-    (if (false? (verify-signature candidate signature key alg))
-      (either/left "Invalid signature.")
-      (let [now (timestamp)
-            stamp (codecs/bytes->long stamp)]
-        (if (and (number? max-age)
-                 (> (- now stamp) max-age))
-          (either/left "Expired data")
-          (either/right (nippy/thaw input {:v1-compatibility? false})))))))
+  (exc/try-on
+   (let [[input signature salt stamp] (str/split data #"\." 4)
+         input (codecs/safebase64->bytes input)
+         signature (codecs/safebase64->bytes signature)
+         salt (codecs/safebase64->bytes salt)
+         stamp (codecs/safebase64->bytes stamp)
+         candidate (bytes/concat input salt stamp)]
+     (when-not (verify-signature candidate signature key alg)
+       (throw+ {:type :validation :cause :auth :message "Message seems corrupt or manipulated."}))
+
+     (let [now (util/timestamp)
+           stamp (codecs/bytes->long stamp)]
+       (when (and (number? max-age) (> (- now stamp) max-age))
+         (throw+ {:type :validation :cause :max-age
+                  :message (format "Token is older than max-age (%s)" max-age)}))
+       (nippy/thaw input {:v1-compatibility? false})))))

 (defn sign
   "Not monadic version of encode."
   [& args]
-  (either/from-either (apply encode args)))
+  (deref (apply encode args)))

 (defn unsign
   "Not monadic version of decode."
   [& args]
-  (let [result (apply decode args)]
-    (when (either/right? result)
-      (either/from-either result))))
+  (deref (apply decode args)))


compojure-api serialises stuff automatically based on accept-headers, no need to do it manually.

--- src/ebot_api/handler.clj
+++ src/ebot_api/handler.clj
@@ -4,9 +4,7 @@
             [schema.core :as s]
             [korma.core :refer :all]
             [korma.db :refer :all]
-            [cheshire.core :as cheshire]
-            [ring.middleware.cors :refer [wrap-cors]]
-            ))
+            [ring.middleware.cors :refer [wrap-cors]]))

 (def db-host
   (or (System/getenv "MYSQL_PORT_3306_TCP_ADDR") "esports-mysql.cr26tvpoftg3.eu-west-1.rds.amazonaws.com"))
@@ -86,22 +84,22 @@
                   :tags ["api"]
                   (GET* "/matches" []
                         :summary "Get all matches"
-                        (ok (cheshire/generate-string(get-all-matchs))))
+                        (ok (get-all-matchs)))
                   (GET* "/match/:id" []
                         :summary "Get match with id"
                         :path-params [id :- Long]
-                        (ok (cheshire/generate-string (get-matchs id))))
+                        (ok (get-matchs id)))
                   (GET* "/rounds/:matchid" []
                         :summary "Get rounds with match id"
                         :path-params [matchid :- Long]
-                        (ok (cheshire/generate-string (get-rounds matchid))))
+                        (ok (get-rounds matchid)))
                   (GET* "/round/:id" []
                         :summary "Get round with id"
                         :path-params [id :- Long]
-                        (ok (cheshire/generate-string (get-round id))))
+                        (ok (get-round id)))
                   (GET* "/team/:id" []
                         :summary "Get team with id"
                         :path-params [id :- Long]
-                        (ok (cheshire/generate-string(get-team id))))
+                        (ok (get-team id)))

                   ))


docstr

docstr

--- src/main/clj/clojure_club/clj_http/programming_quotes_api.clj
+++ src/main/clj/clojure_club/clj_http/programming_quotes_api.clj
@@ -1,4 +1,5 @@
 (ns clojure-club.clj-http.programming-quotes-api
+  "Examples built around https://github.com/skolakoda/programming-quotes-api"
   (:require [clj-http.client :as client]))

 (defn all-quotes []


Rename group-society? to tribe-society?

Rename group-society? to tribe-society?

It was renamed by mistake before, putting back the original name.

--- src/civs/model/society.clj
+++ src/civs/model/society.clj
@@ -42,7 +42,7 @@
 (defn band-society? [group]
   (= :band (.society group)))

-(defn group-society? [group]
+(defn tribe-society? [group]
   (= :tribe (.society group)))

 (defn chiefdom-society? [group]


add link to battle header

add link to battle header

--- src/client/pages/play.cljs
+++ src/client/pages/play.cljs
@@ -71,7 +71,8 @@

 (hiccups/defhtml battle-header []
   [:div.hdr-93a4f
-    [:img.logo-dd80d {:src "/img/t3tr0s_logo_200w.png" :alt "T3TR0S Logo"}]
+    [:a {:href "#/menu"}
+      [:img.logo-dd80d {:src "/img/t3tr0s_logo_200w.png" :alt "T3TR0S Logo"}]]
     [:h1.title-6637f "Battle"]
     [:a.spectate-link-02d2e {:href "#/spectate" :target "_blank"}
       "Spectate"]])


Primitive sharing for pess/opt

Primitive sharing for pess/opt

--- src/angelic/search/implicit/dash_astar.clj
+++ src/angelic/search/implicit/dash_astar.clj
@@ -15,6 +15,9 @@
 ;;  1.  Give subproblems a bound before they have output.
 ;;  2.  Account for necessary inconsistency with implicit descriptions.

+;; Note: assume optimistic description is exact when solved-terminal, share with pess
+;; (only when output-collecting on...)
+
 ;; TODO: tests !

 ;;;;; Subsumption
@@ -23,19 +26,21 @@
 ;; TODO: more generic propagation?  (We know: names, subs. relationships on sets.  Efficient lookups?)
 ;; TODO: children wait on one (or more) subsumption parents.

-
 ;;;;; Pessimistic
-;; TODO: add pessimistic variants (shared primitives)
-;; TODO: bounding pressimistic descritpions (assume consistency for now)
 ;; TODO: hook up pess/opt with same input set?
-;; TODO: pruning.
+;; TODO: pruning. ?
+;; --> TODO: empty-set subproblems for pessimistic.
+;; --> TODO: Cannot propagate upper bounds from pessimistic subproblems
+;;           in the presence of sharing, since they may reflect other opt SPs.

 ;;;;; Tree construction
+;; -> TODO: dijkstra variants for cyclic actions ??
 ;; TODO: smarter output-collector (semantic) -- problems here though.
 ;; TODO: don't always split-left?
 ;; TODO: don't release children until they have lower reward or are primitive?
+;;--> TODO: alternative child release strategies, e.g. wait 'til solved
 ;; TODO: make sure dead stuff can be GC'd
-;; TODO: alternative child release strategies, e.g. wait 'til solved
+;; TODO: note no difference between syntax and semantics for single state ...

 ;;;;; Summaries and solving
 ;; TODO: lazy/pseudo-solve (regular seems impossible; bounds mean apparent decrease may be increase.
@@ -44,6 +49,7 @@
 ;; TODO: smarter choose-leaf?
 ;; TODO: conspiracy number, weighted, etc.
 ;; TODO: forcing summary of TS in summary_graphs makes a lot of extra comps (lefts), doesn't help.
+;; TODO: propagate across subsumption links? (must be careful here, not to cross state/plan syntax/semantics line)

 ;;;;; SP caching
 ;; TODO: tail (i.e., pair) caching? -- Only help for >2 len refs...
@@ -57,15 +63,6 @@
 ;; Can be implemented by not letting children go until they have subs...
 ;;  (and not incorporating into summary, except as bound) .... ?

-;;!! --> TODO: try holding back children until solved?
-
-;; TODO: problem with propagation??
-;;  (some subsumption links are semantic, not syntactic -- propagating these is wrong?)
-;;  i.e., empty-set subproblem is subsumed by everything --
-;;  What we have is OK, we just need to be careful if we implement refine-input propagation.
-
-;; TODO: empty-set subproblems for pessimistic.
-;; TODO: share primitive subproblems...

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;       Options      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -80,11 +77,11 @@
 (declare *state-abstraction*     ) ;; Use state abstraction?  Requires *decompose-cache*
 (declare *propagate-subsumption* ) ;; Automatically propagate subsumption links to corresponding children
 (declare *make-pess-summary*     ) ;; fn of [min-reward max-reward status source children]
+(def *share-terminal* true       )

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;       Utilities      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-

 ;;;;;;;;;;;;;;;;;;;;;;;;;;         PubSubHub          ;;;;;;;;;;;;;;;;;;;;;;;;;;

@@ -529,16 +526,24 @@
      (if (=-state-sets (get-output-set! inner-sp) (get-output-set! child-sp))
        (do (schedule-increase! sp) (connect-and-watch! sp child-sp nil #(child-watch sp %)))
        (add-sp-child! sp (make-output-collecting-subproblem fs inp-key child-sp) :irrelevant)))
-   (fn refine-input [s ni]
+   (fn oc-refine-input [s ni]
      (let [ninp-key (get-input-key fs ni)]
-       (if (= inp-key ninp-key)
-         s
-         (if (= :Atomic (first (sp-name inner-sp)))
-           (let [ret (get-ocs (sp-name inner-sp) fs ninp-key ni)]
-             (util/assert-is (not (identical? (canonicalize ret) inner-sp)) "%s" [(def *bad* [s inner-sp (input-set s) ni])])
-             (add-subsuming-sp! (canonicalize ret) inner-sp)
-             ret)
-           (make-output-collecting-subproblem fs ninp-key (refine-input inner-sp (log-input fs ni)))))))))
+       (cond (= inp-key ninp-key) s
+             (and *share-terminal* (solved-terminal? inner-sp))
+               (let [r (summary/max-reward (sg/summary inner-sp))
+                     ret (make-subproblem (oc-name (sp-name inner-sp)) ni nil
+                           (fn [_] (throw (RuntimeException.)))
+                           (fn [_ _] (throw (RuntimeException.)))
+                           (fn [s] (make-summary ni r :solved s r)))]
+                 (assert (and (= :opt (first inp-key)) (= :pess (first ni))))
+                 (set-output-set! ret [:pess (second (get-output-set! inner-sp))])
+                 ret)
+             (= :Atomic (first (sp-name inner-sp)))
+               (let [ret (get-ocs (sp-name inner-sp) fs ninp-key ni)]
+                 (util/assert-is (not (identical? (canonicalize ret) inner-sp)) "%s" [(def *bad* [s inner-sp (input-set s) ni])])
+                 (add-subsuming-sp! (canonicalize ret) inner-sp)
+                 ret)
+             :else (make-output-collecting-subproblem fs ninp-key (refine-input inner-sp (log-input fs ni))))))))

 (defn get-ocs [inner-n fs inp-key inp-set]
   (let [make-sp #(make-output-collecting-subproblem fs inp-key (get-subproblem inner-n (log-input fs inp-set)))]
@@ -606,7 +611,7 @@
    #(let [n (fs/fs-name (second (sp-name %)))] (when-not (= (first n) :noop) n))))

 ;; ???
-(defn solve-pess [opt-root choice-fn local?]
+#_ (defn solve-pess [opt-root choice-fn local?]
   (let [pess-root (sp-ts (refine-input (ts-sp opt-root) [:pess (second (input-set (ts-sp opt-root)))]))
         counter   (atom 0)]
     (def *pess-root* pess-root)
@@ -648,7 +653,9 @@
     (summary/solve
      #(sg/summary pess-root)
      (sg/best-leaf-operator choice-fn local? evaluate-and-update!)
-     #(let [n (fs/fs-name (second (sp-name %)))] (when-not (= (first n) :noop) n)))))
+     #(let [[t in-name] (sp-name %)
+            n (case t :OC (fs/fs-name (second in-name)) :Atomic (fs/fs-name in-name))]
+        (when-not (= (first n) :noop) n)))))

 (defn implicit-dash-wa* [henv w & opts]
   (binding [summary/*sws-weight* w
@@ -671,11 +678,9 @@
 ;; (dotimes [_ 1] (reset! sg/*summary-count* 0) (reset! summaries-old/*summary-count* 0) (debug 0 (let [opts [:gather true :d true :s :eager :dir :right] h (make-discrete-manipulation-hierarchy  (make-random-hard-discrete-manipulation-env 3 3))]   (time (println (run-counted #(identity (apply da/implicit-dash-a* h opts))) @sg/*summary-count*))   (time (println (run-counted #(identity (apply dao/implicit-dash-a*-opt h opts))) @summaries-old/*summary-count*))   (time (println (run-counted #(identity (dam/implicit-random-dash-a*-opt h))) ))   (time (println (run-counted #(identity (his/explicit-simple-dash-a* h))) )) )))

-;; TODO: bug in
-
-;; (dotimes [_ 1] (reset! sg/*summary-count* 0) (reset! summaries-old/*summary-count* 0) (debug 0 (let [opts [:gather true :d false :s false :dir :right] h (make-nav-switch-hierarchy (make-random-nav-switch-env 20 5 1) true)]   (time (println (run-counted #(identity (apply da/implicit-dash-wa* h 1.2 opts))) @sg/*summary-count*))  (time (println (run-counted #(identity (apply da/implicit-dash-a* h opts))) @sg/*summary-count*))   )))
-
-;; TODO: where are upper bounds going / comine from ?
+
+
+

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Graveyard ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


adding test test

adding test test

--- src/leiningen/new/closp.clj
+++ src/leiningen/new/closp.clj
@@ -75,7 +75,7 @@

               ["README.md" (*render* "README.md")]

-              [(str "test/clj/db/{{san-path}}/user_test.cljs") (*render* "test/clj/db/user_test.cljs")]
+              [(str "test/clj/db/{{san-path}}/user_test.clj") (*render* "test/clj/db/user_test.clj")]

               ]))


don't optimize core for now, should be addressed separately for all builds

--- src/clj/cljs/repl/node.clj
+++ src/clj/cljs/repl/node.clj
@@ -93,7 +93,8 @@
                       (assoc opts
                         :output-file
                         (closure/src-file->target-file core)
-                        :static-fns true))
+                        ;:static-fns true
+                        ))
             deps    (closure/add-dependencies opts core-js)]
         ;; output unoptimized code and the deps file
         ;; for all compiled namespaces


Move from duck-streams to io.

Move from duck-streams to io.

--- src/clj/fleetdb/server.clj
+++ src/clj/fleetdb/server.clj
@@ -3,7 +3,7 @@
   (:require (fleetdb [file :as file] [thread-pool :as thread-pool]
                      [lint :as lint] [embedded :as embedded])
             (clj-stacktrace [repl :as stacktrace])
-            (clojure.contrib [str-utils :as str-utils] [duck-streams :as du])
+            (clojure.contrib [io :as io])
             (clj-json [core :as json]))
   (:import  (java.net ServerSocket Socket InetAddress)
             (java.io BufferedWriter OutputStreamWriter
@@ -17,7 +17,7 @@

 (def fleetdb-version
   (let [stream  (.getResourceAsStream (RT/baseLoader) "project.clj")]
-    (nth (read-string (du/slurp* stream)) 2)))
+    (nth (read-string (io/slurp* stream)) 2)))

 (defn- info-map [dba]
   (let [base {"fleetdb-version" fleetdb-version}


fix encountered check on self-trashing ICE

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -190,7 +190,7 @@
    "Data Mine"
    {:abilities [{:msg "do 1 net damage"
                  :effect (req (damage state :runner :net 1 {:card card})
-                              (when (= current-ice card)
+                              (when current-ice
                                 (trash-ice-in-run state))
                               (trash state side card))}]}

@@ -403,7 +403,7 @@
    "Its a Trap!"
    {:expose {:msg "do 2 net damage" :effect (effect (damage :net 2 {:card card}))}
     :abilities [(assoc trash-installed :effect (req (trash state side target {:cause :subroutine})
-                                                    (when (= current-ice card)
+                                                    (when current-ice
                                                       (trash-ice-in-run state))
                                                     (trash state side card)))]}

@@ -425,7 +425,7 @@
                                       :player :runner
                                       :msg (msg "force the Runner to trash " (:title target))
                                       :effect (req (trash state side target)
-                                                   (when (= current-ice card)
+                                                   (when current-ice
                                                      (trash-ice-in-run state))
                                                    (trash state side card)))]}

@@ -701,7 +701,7 @@
    "Special Offer"
    {:abilities [{:label "Gain 5 [Credits] and trash Special Offer"
                  :effect (req (gain state :corp :credit 5)
-                              (when (= current-ice card)
+                              (when current-ice
                                 (trash-ice-in-run state))
                               (trash state side card)
                               (system-msg state side (str "gains 5 [Credits] and trashes Special Offer")))}]}
@@ -834,7 +834,7 @@
                                          (> (count (concat (:ices (card->server state card))
                                                            (:content (card->server state card)))) 1))
                                 (prevent-jack-out state side))
-                              (when (= current-ice card)
+                              (when current-ice
                                 (trash-ice-in-run state))
                               (trash state side card))}]}


New message related to changes in GitHub ownership

--- src/clj_mrazik/irc_bot.clj
+++ src/clj_mrazik/irc_bot.clj
@@ -283,6 +283,7 @@
                           "die"      "thanks for your feedback, I appreciate it"
                           "Good bot" "I know"
                           "Good bot." "I know"
+                          "ms"       "The current Microsoft is *NOTHING* like the old Microsoft. They have excellent people who really get Open Source. There's no reason to stop using github except outdated and outmoded feelings from yesteryear. The Microsoft of 2018 are our friends. They're not the Borg. They're not out to Embrace, Extend, Extinguish all we hold dear."
                           "quote"    (say-quote quotes)
                           "hlaska"   (say-quote quotes)
                           "papalas"  (say-quote papalas)


parse nashorn nested defs

parse nashorn nested defs

--- src/cljs_api_gen/parse.clj
+++ src/cljs_api_gen/parse.clj
@@ -835,10 +835,20 @@

 (defmethod parse-ns ["cljs.repl.nashorn" :compiler] [ns- api]
   (cond
-    (>= *cljs-num* 3255) nil ;; FIXME: parse defs from
-    ;; (util/compile-if (Class/forName "jdk.nashorn.api.scripting.NashornException")
-    ;;   (do ... ))
-    (>= *cljs-num* 0) (parse-ns* ns- "clojurescript" :compiler)))
+    (>= *cljs-num* 3255)
+    (let [forms (apply concat (read-ns-forms ns- :compiler))
+          ;; get nested forms inside:
+          ;;   (util/compile-if (Class/forName "jdk.nashorn.api.scripting.NashornException")
+          ;;     (do ... ))
+          [_compile-if _class [_do & nested-forms]] (first
+                                                      (filter
+                                                        #(and (list? %) (= 'util/compile-if (first %)))
+                                                        forms))]
+      (cond-> (parse-ns* ns- "clojurescript" :compiler)
+        nested-forms (concat (parse-forms ns- "clojurescript" nested-forms))))
+
+    (>= *cljs-num* 0)
+    (parse-ns* ns- "clojurescript" :compiler)))

 (defmethod parse-ns [:default :library] [ns- api]
   (parse-ns* ns- "clojurescript" :library))


doc string for partitionwise sampled rdd

--- src/clojure/flambo/api.clj
+++ src/clojure/flambo/api.clj
@@ -112,6 +112,7 @@
   ([spark-context lst num-slices] (.parallelize spark-context lst num-slices)))

 (defn partitionwise-sampled-rdd [rdd sampler seed]
+  "Creates a PartitionwiseSampledRRD from existing RDD and a sampler object"
   (-> (PartitionwiseSampledRDD. (.rdd rdd) sampler seed k/OBJECT-CLASS-TAG k/OBJECT-CLASS-TAG)
       (JavaRDD/fromRDD k/OBJECT-CLASS-TAG)))


Fixed save.

Fixed save.

--- src/divergence/system.cljs
+++ src/divergence/system.cljs
@@ -378,7 +378,7 @@
 (defn serialize [entities]
   (doseq [e entities]
       (reset! serial-data @e) ;loops through and copies entities into serial-data
-      (swap! serial-data dissoc :ref :sprite :stage :actions :tiling-sprite :on-stage) ;takes out complex data
+      (swap! serial-data dissoc :ref :sprite :stage :actions :tiling-sprite :on-stage :container) ;takes out complex data
       ;(js/alert (pr-str @serial-data))
       (save-to-local-db (pr-str (e/entity-atom->component-val e :name)) @serial-data))) ;save to local database


spliting the handling of pre and post exceptions on the contract side

--- src/fogus/me/trammel.clj
+++ src/fogus/me/trammel.clj
@@ -103,38 +103,48 @@
     ([f x] {:pre [(foo x)] :post [(bar %)]} (f x))
   "
   [cnstr]
+  (println "FOO!")
   (let [[args pre-post-map] cnstr]
     (list (into '[f] args)
-          (list 'try
-                (list
-                 (list 'fn [] pre-post-map
-                       (list* 'f (mapcat (fn [item]
-                                           (cond (symbol? item) [item]
-                                                 (map? item) [(:as item)]
-                                                 :else [item]))
-                                         args))))
-                (list 'catch 'AssertionError 'e
-                  (list 'throw '(Exception. "foo")))))))
+          (list 'let ['ret (list 'try
+                                 (list (list 'fn []
+                                             (select-keys pre-post-map [:pre])
+                                             (list* 'f (mapcat (fn [item]
+                                                                 (cond (symbol? item) [item]
+                                                                       (map? item) [(:as item)]
+                                                                       :else [item]))
+                                                               args))))
+                                 (list 'catch 'AssertionError 'pre
+                                       (list 'throw (list 'AssertionError. (list 'str "Pre-condition failure! " (list '.getMessage 'pre))))))]
+                (list 'try
+                      (list (list 'fn []
+                                  (select-keys pre-post-map [:post])
+                                  'ret
+                                  ))
+                      (list 'catch 'AssertionError 'post
+                            (list 'throw (list 'AssertionError. (list 'str "Post-condition failure! " (list '.getMessage 'post))))))))))

 (comment
-  (build-contract '[[x] {:pre [(foo x)] :post [(bar %)]}])
-  ([f x]
-     (try
-       ((fn []
-          {:pre [(foo x)], :post [(bar %)]}
-          (f x)))
-       (catch AssertionError e
-         (throw (Exception. 'foo)))))
-
-  (defn foo [a b]
-    (try
-      ((fn []
-         {:pre [(number? a)]}
-         [a b]))
-      (catch AssertionError _
-        (throw (Exception. "har!")))))
-
-  (foo :a 2))
+  (build-contract '[[x y] {:pre [(number? x)] :post [(pos? %)]}])
+
+  (defn foo [f n]
+    (let [ret (try
+                ((fn []
+                   {:pre [(number? n)]}
+                   (f n n)))
+                (catch AssertionError pre
+                  (throw (AssertionError. (str "Pre-condition failure! " (.getMessage pre))))))]
+      (try
+        ((fn []
+           {:post [(pos? %)]}
+           ret))
+        (catch AssertionError post
+          (throw (AssertionError. (str "Post-condition failure! " (.getMessage post))))))))
+
+  (foo + 1)
+  (foo + 'a)
+  (foo + -4)
+)

 (defmacro contract
   "The base contract form returning a higher-order function that can then be partially
@@ -309,6 +319,16 @@
   (defconstrainedtype Bar [a 4 b 8] [(every? pos? [a b])])
   (Bar? (new-Bar))

+(defn sqr [n]
+  (* n n))
+
+(provide-contracts
+ [sqr "The constraining of sqr" [n] [number? (not= 0 n) => pos? number?]])
+
+(sqr 0)
+
+ (positive-nums -1)
+
   (type (new-Bar))

   (.a (new-Bar  42 77))


Give credit to Quiescent author

Give credit to Quiescent author

--- src/literate_2048/core.cljs
+++ src/literate_2048/core.cljs
@@ -231,10 +231,11 @@
 ;; Because manually manipulating the DOM is messy, we'll let
 ;; [Quiescent](https://github.com/levand/quiescent) do it for us instead.
 ;; Quiescent is an abstraction over [React](http://facebook.github.io/react)
-;; that leverages immutability. We are responsible only for supplying a
-;; specification of what the UI should look like at a given moment. Quiescent
-;; will rely on React to generate the minimal set of changes that need to be
-;; applied to the DOM.
+;; that leverages immutability written by
+;; [Luke VanderHart](https://twitter.com/levanderhart). We are responsible only
+;; for supplying a specification of what the UI should look like at a given
+;; moment. Quiescent will rely on React to generate the minimal set of changes
+;; that need to be applied to the DOM.

 ;; Elements are placed on the board on well established positions by wrapping
 ;; them in a div with the "pos" and "pos-i-j" classes, where i and j are numbers


Add transformation core/filter-column spec [skip ci]

--- backend/specs/akvo/lumen/specs/transformation.clj
+++ backend/specs/akvo/lumen/specs/transformation.clj
@@ -170,6 +170,26 @@
             ::transformation.engine/op]))

+(create-ns  'akvo.lumen.specs.transformation.filter-column)
+(alias 'transformation.filter-column 'akvo.lumen.specs.transformation.filter-column)
+
+(s/def ::transformation.filter-column/is string?)
+(s/def ::transformation.filter-column/contains string?)
+(s/def ::transformation.filter-column/expression (s/keys
+                                                  :opt-un [::transformation.filter-column/is
+                                                           ::transformation.filter-column/contains]))
+
+(s/def ::transformation.filter-column/args
+  (s/keys :req-un [::db.dsv.column/columnName
+                   ::transformation.filter-column/expression]))
+
+(defmethod op-spec :core/filter-column  [_]
+  (s/keys
+   :req-un [::transformation.filter-column/args
+	    ::transformation.engine/onError
+            ::transformation.engine/op]))
+
+
 (lumen.s/sample ::transformation.engine/op-spec 10)

 (create-ns  'akvo.lumen.specs.dataset-version.transformation)


(maint) Remove test using /metrics/v1

(maint) Remove test using /metrics/v1

--- test/puppetlabs/puppetdb/integration/puppetserver_metrics.clj
+++ test/puppetlabs/puppetdb/integration/puppetserver_metrics.clj
@@ -55,37 +55,4 @@
                  :value
                  vals
                  (map #(not= 0.0 %))
-                 (every? true?)))))
-
-    (testing "PuppetDB doesn't create duplicate command metrics"
-      (let [bulk-metrics-req (fn [metrics]
-                               (let [{:keys [status body]}
-                                     (svc-utils/post-ssl (str "https://localhost:"
-                                                              (-> pdb int/server-info :base-url :port)
-                                                              "/metrics/v1/mbeans")
-                                                         metrics)]
-                                 {:status status
-                                  :body (-> body slurp json/parse-string)}))
-
-            ;; these metrics use the normalized command name and should be populated
-            normalized-metrics (bulk-metrics-req ["puppetlabs.puppetdb.mq:name=replace facts.5.seen"
-                                                  "puppetlabs.puppetdb.mq:name=store report.8.seen"
-                                                  "puppetlabs.puppetdb.mq:name=replace catalog.9.seen"])
-
-            ;; these metrics were the duplicates being seen in PDB-3417 they use
-            ;; the command name from the query param before normalization and shouldn't be populated
-            improper-metrics (bulk-metrics-req ["puppetlabs.puppetdb.mq:name=replace_facts.5.seen"
-                                                "puppetlabs.puppetdb.mq:name=store_report.8.seen"
-                                                "puppetlabs.puppetdb.mq:name=replace_catalog.9.seen"])]
-
-        ;; check that normalized metrics are populated
-        (let [{:keys [status body]} normalized-metrics]
-          (is (= 200 status))
-          (is (= 3 (count body)))
-          (is (every? some? body)))
-
-        ;; check that the improperly formated metrics are no longer being created
-        (let [{:keys [status body]} improper-metrics]
-          (is (= 200 status))
-          (is (= 3 (count body)))
-          (is (every? nil? body)))))))
+                 (every? true?)))))))


Exclude apostrophes from boundary matching with keywords

--- src/marcgrep/predicates.clj
+++ src/marcgrep/predicates.clj
@@ -3,7 +3,8 @@
   (:use marcgrep.config
         [clojure.string :only [join]])
   (:import [org.marc4j.marc Record VariableField DataField ControlField
-            Subfield]))
+            Subfield]
+           [java.util.regex Pattern]))

 (defn matching-fields [^Record record fieldspec]
   (filter (fn [^VariableField field]
@@ -32,17 +33,20 @@
          fields)))

+(defn keyword-regexp [keyword]
+  (let [boundary "(^|$|[\\p{Space}\\p{Punct}&&[^']])"]
+    (re-pattern (str "(?i)" boundary "\\Q" keyword "\\E" boundary) )))
+
+
 (defn contains-keyword? [record fieldspec ^String value]
-  (let [pattern (re-pattern (format "(?i)\\b\\Q%s\\E\\b"
-                                    value))]
+  (let [^Pattern pattern (keyword-regexp value)]
     (some (fn [^String fv] (.find (.matcher pattern fv)))
           (field-values record fieldspec))))

 (defn does-not-contain-keyword? [record fieldspec ^String value]
   (when-let [fields (field-values record fieldspec)]
-    (let [pattern (re-pattern (format "(?i)\\b\\Q%s\\E\\b"
-                                      value))]
+    (let [^Pattern pattern (keyword-regexp value)]
       (not-any? (fn [^String fv] (.find (.matcher pattern fv)))
                 fields))))


add a quick conditional to our current-user-id middleware to ensure it doesn't attempt to validate the session if we haven't initialized the app yet.

--- src/metabase/middleware.clj
+++ src/metabase/middleware.clj
@@ -52,7 +52,7 @@
   [handler]
   (fn [{:keys [metabase-session-id] :as request}]
     ;; TODO - what kind of validations can we do on the sessionid to make sure it's safe to handle?  str?  alphanumeric?
-    (handler (or (when metabase-session-id
+    (handler (or (when (and metabase-session-id ((resolve 'metabase.core/initialized?)))
                    (when-let [session (first (k/select Session
                                                        ;; NOTE: we join with the User table and ensure user.is_active = true
                                                        (k/with User (k/where {:is_active true}))


Add flat to kill async process

Add flat to kill async process

--- frontend/src/cruncher/communication/progress.cljs
+++ frontend/src/cruncher/communication/progress.cljs
@@ -29,6 +29,7 @@

 (defn query-status
   "Make ajax request to request status of the crunching-progress."
+<<<<<<< da416801d037474fa44e000aeee4d19da7bd2c16
   [this]
   (lib/progress! true)
   (let [channel (chan)]
@@ -45,6 +46,22 @@
               (do (close! channel)
                   (lib/progress! false))))
           ))))
+=======
+  []
+  (lib/progress! true)
+  (go (while (lib/progress?)
+        (let [url (:status-delete config/api)
+              progress (lib/get-progress-status)
+              to-delete (:to-delete progress)
+              deleted (:deleted progress)
+              status (:status progress)]
+          (if (and (= status "ok") (not= to-delete deleted))
+            (do
+              (<! (timeout 500))
+              (lib/progress! true)
+              (com/ajax-get url update-progress-handler error-handler))
+            (lib/progress! false))))))
+>>>>>>> Add flat to kill async process

 (defui ProgressBar
   Object


Might as well be specific

Might as well be specific

--- src/overcode/introvert.cljs
+++ src/overcode/introvert.cljs
@@ -76,11 +76,11 @@
    (cond
     (and (arr? val1) (arr? val2))
     (and (= (count val1) (count val2))
-         (every? identity (map #(deep= %1 %2 visited) val1 val2)))
+         (every? true? (map #(deep= %1 %2 visited) val1 val2)))

     (and (obj? val1) (obj? val2))
     (and (= (obj-size val1) (obj-size val2))
-         (every? identity (map #(deep= %1 %2 visited) (js/Object.keys val1) (js/Object.keys val2)))
+         (every? true? (map #(deep= %1 %2 visited) (js/Object.keys val1) (js/Object.keys val2)))
          (every? #(deep= (aget val1 %) (aget val2 %) visited) (js/Object.keys val1)))

     :else (= val1 val2)))


add missing arg

add missing arg

--- src/overtone/repl/ugens.clj
+++ src/overtone/repl/ugens.clj
@@ -69,7 +69,7 @@
         longest-name-len (length-of-longest-string names)]
     (if (empty? specs)
       (println "Sorry, unable to find a matching ugen.")
-      (print-ug-summaries longest-name-len))))
+      (print-ug-summaries specs longest-name-len))))

 (defn find-ug-doc
   "Find a ugen containing the specified terms which may be either strings or


translate client-uuid to user-id

translate client-uuid to user-id

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -1,6 +1,7 @@
 (ns pc.http.sente
   (:require [clojure.core.async :as async]
             [clojure.set :as set]
+            [clojure.string :as str]
             [clojure.tools.logging :as log]
             [taoensso.sente :as sente])
   (:import java.util.UUID))
@@ -8,8 +9,10 @@
 ;; TODO: find a way to restart sente
 (defonce sente-state (atom {}))

-(defn user-id-fn [ring-req]
-  (UUID/randomUUID))
+(defn user-id-fn
+  "Have to remove - so that we can parse it out of the client-uuid"
+  [ring-req]
+  (str/replace (UUID/randomUUID) "-" ""))

 ;; hash-map of document-id to set of connected user-ids
 ;; Used to keep track of which transactions to send to which user
@@ -23,6 +26,11 @@

 (defn ws-handler-dispatch-fn [req]
   (-> req :event first))
+
+(defn client-uuid->uuid
+  "Get the client's user-id from the client-uuid"
+  [client-uuid]
+  (str/replace client-uuid #"-.*$" ""))

 (defmulti ws-handler ws-handler-dispatch-fn)

@@ -44,7 +52,7 @@

 (defmethod ws-handler :chsk/uidport-close [{:keys [client-uuid] :as req}]
   (log/infof "closing connection for %s" client-uuid)
-  (clean-document-subs client-uuid))
+  (clean-document-subs (client-uuid->uuid client-uuid)))

 (defn subscribe-to-doc [document-id uuid]
   (swap! document-subs update-in [document-id] (fnil conj #{}) uuid))
@@ -52,7 +60,7 @@
 (defmethod ws-handler :frontend/subscribe [{:keys [client-uuid ?data] :as req}]
   (let [document-id (-> ?data :document-id)]
     (log/infof "subscribing %s to %s" client-uuid document-id)
-    (subscribe-to-doc document-id client-uuid)))
+    (subscribe-to-doc document-id (client-uuid->uuid client-uuid))))

 (defn setup-ws-handlers [sente-state]
   (let [tap (async/chan (async/sliding-buffer 100))


Replace run! with dorun and map

Replace run! with dorun and map

This makes mount compatible with older Clojure versions again.

--- src/mount/core.clj
+++ src/mount/core.clj
@@ -119,7 +119,8 @@
   (let [done (atom [])]
     (->> states
          (sort-by (comp :order meta) order)
-         (run! #(fun % (meta %) done)))
+         (map #(fun % (meta %) done))
+         dorun)
     @done))

 (defn- merge-lifecycles
@@ -159,17 +160,17 @@

 (defn stop [& states]
   (let [states (or states (find-all-states))
-        _ (run! unsub states)     ;; unmark substitutions marked by "start-with"
+        _ (dorun (map unsub states))     ;; unmark substitutions marked by "start-with"
         stopped (bring states down >)]
-    (run! rollback! states)       ;; restore to origin from "start-with"
+    (dorun (map rollback! states))       ;; restore to origin from "start-with"
     {:stopped stopped}))

 (defn stop-except [& states]
   (let [all (set (find-all-states))
         states (remove (set states) all)
-        _ (run! unsub states)     ;; unmark substitutions marked by "start-with"
+        _ (dorun (map unsub states))     ;; unmark substitutions marked by "start-with"
         stopped (bring states down >)]
-    (run! rollback! states)       ;; restore to origin from "start-with"
+    (dorun (map rollback! states))       ;; restore to origin from "start-with"
     {:stopped stopped}))

 (defn start-with-args [xs & states]